GitHub Pages Custom Domain HTTPS

GitHub Pages

等了好久終於出來的功能,追了蠻久,昨天 DK 也有提到,其實正式發佈前就看到有人已經可以用了,不過總之這篇稍微記錄一下如果已經是舊有的 GitHub Pages 還不能用可以怎麼處理,不過不完全有效,舊有的專案在設定看起來會像是:

GitHub Pages

下面有寫說因為用了 custom domain 就不能用,這時候把 custom domain 刪除,然後儲存重新加回去就會變成:

GitHub Pages

然後就等,我大概是等到隔天就有了(變成第一張圖的狀態),不過這幾天剛好完全沒空,到現在才有空檔紀錄一下。


Dank Mono

Dank Mono Regular,

上週在 Twitter 上看到有人轉推作者的發文,發現這個新的 coding 字型:Dank Mono,然後我就買來用用看了,在這之前我是用Source Code Pro的,一剛開始設定下去覺得還有點不習慣,不過強迫用了一下卻適應的蠻快的。

套用上我的編輯環境後是這樣:

Dank Mono,

閱讀「Dank Mono」全文

TFN 域名轉出

dig markdown.tw,

我的 markdown.tw 在 TFN 註冊的,其實一直很想轉出,但是很怕轉的過程出意外,遲遲沒動手。不過剛剛看到 GitHub Pages 用 custom domain 也正式支援 HTTPS 了,如果是設定 A record 的話需要更新 DNS 設定,於是我就決定認真的來處理這件事,不意外的介面很難理解,決定記錄一下幫助眾生~

閱讀「TFN 域名轉出」全文

ESLint Plugin 入門

ESLint

最近寫了個簡單的 ESLint plugin,來記錄一下一些基礎知識,我做的 plugin 很簡單,叫做eslint-plugin-no-parameter-e,這個 ESLint plugins 做的事情只是檢查所有 function 的參數,然後如果有任何一個參數名是e的話就警報,這條 rule 其實是為了避免把errorevent簡寫成e,會容易混淆。

接下來進入正題,ESLint 基本上就是透過ESPree這個 parser 先把程式碼轉為ESTree相容的 AST,EStree 是個 de facto standard,是從 Mozilla Spider Monkey 用的 AST 演化而來,現在幾乎做 JavaScript 工具,會需要轉 AST 的話都會用這個格式;有了 AST 後,才來分析 AST 做檢查,然後現在有工具叫AST Explorer,非常方便,可以線上直接修改 code sample 看 AST 變化,可以用它來看你想要處理的 code 的 AST 結構,至於怎麼寫 rule 就看個人了,基本上就是監聽要注意的 node,然後檢查 AST 結構,有問題就呼叫 report 這樣。

第二點,npm module 的名稱要用eslint-plugin-開頭,官方說的規則,應該不遵守還是可以抓的到,不過就還是遵守一下免的有意外。

第三點,測試其實 ESLint 有 RuleTester 可以拿來寫測試用:

const rule = require('../rule.js')
const RuleTester = require('eslint').RuleTester

const ruleTester = new RuleTester();

ruleTester.run('no-parameter-e', rule, {
  valid: [
    'function a (event) {}',
  ],
  invalid: [
    {
      code: 'function e (e) {}',
      errors: [{ message }],
    }
  ],
});

很方便,都不用 test framework 了,並且有特別要求 valid 和 invalid 都要有 test case,不然測試就會失敗。

然後測試的時候是每個 rule 獨立跑,每個 plugin 可以有多個 rule,很多 plugin 是把不同 rule 都獨立一個檔案,每個 rule 可以丟的東西除了檢查外還有不少,像是說明文件、自動修復的動作等,詳見官方文件,我一開始是參考eslint-plugin-import的,不過現在初心者應該也可以先看我的eslint-plugin-no-parameter-e,東西更少一些。

下一個想來挑戰處理空行,看了一下感覺是比較困難啊~


Immer 原理

前陣子有個蠻有趣的 library 叫Immer,是 MobX 的開發者 Michel Weststrate 做的,這個 library 做的事情很有趣,它整合了 immutable 資料和原生資料的特性,反過來從缺點來看,immutable 資料型態的問題就是操作比較不方便,所有的修改動作都要透過 method 來執行,不能直接用 assign 的,有時候要改比較深層一點的資料就很麻煩,像 Facebook 的immutable.js就需要用getInupdateIn來處理:

getIn({ x: { y: { z: 123 }}}, ['x', 'y', 'z']) // 123

const original = { x: { y: { z: 123 }}}
setIn(original, ['x', 'y', 'z'], 456) // { x: { y: { z: 456 }}}

用陣列丟每層的屬性名稱,也有一些是用.切分的 path 來處理這個問題(像是prop1.prop2.prop3這種結構),而原生資料的缺點,在這個場景來看當然就是不 immutable 了,Immer 就提出了一個新的構想,把這兩者的優點結合在一起,讓資料可以保持 immutable 特性,又可以直接修改,當然不能直接修改 JavaScript 行為,所以還是有些地方需要等價交換,就是修改資料的時候,要包進 produce function 內:

const nextState = produce(baseState, draftState => {
    draftState.push({ todo: "Tweet about it" })
    draftState[1].done = true
})

然後得到的nextStatebaseState就會是不同物件,就像是 immutable 物件一樣行為,所以如果沒修改就還是同個物件,初看覺得有點黑魔法,不過思考過後覺得也不是不能做,有了些假想的實做方法後去研究了一下程式碼,不太意外的其實在 produce 裡面拿到的 draft 物件,是一個Proxy包裝過的物件,然後 immutable 相關的邏輯都做在 Proxy 內,produce 跑完後再把新的值 finalize 取出用 plain object 傳回給nextState,當然因為 Proxy 是比較新的東西,所以針對 ES5 也有另外的處理,我大致看一下就是比較土法煉鋼的下去比對,至於為什麼不全部都這樣做應該是效能考量吧。其實我覺得比起實做的原理,能想到這樣設計實在是很厲害,不像大部分人早就放棄了,還持續思考是不是有更好的作法可以整合兩種資料格式的優點才有機會找到這條路。

最後,Immer 這名字的由來,雖然在德文有這單字,不過我判斷應該還是從 immersive 來的吧。


➡ 看看其它文章