免費 CDN 玩法 —— 檔案一鍵上傳到 NPM
前言
unpkg、jsdelivr 等站點可加速 NPM 包檔案,適合作為個人網站或演示案例的免費 CDN。
雖然上傳檔案到 NPM 很簡單,建立 package.json
然後 npm publish
即可,但之後更新卻很麻煩 —— 即使只更新一個檔案,也要發一個新版本的包。由於 URL 包含版本號,因此所有檔案的 URL 都會變化,導致無法利用快取。
當然也可以增量釋出,每次只發布變化的檔案,從而充分利用已有的檔案。但這需記錄每個檔案的狀態,實現起來較為麻煩。
無狀態
這裡講解一種更巧妙的方案 —— 使用檔案 Hash 作為版本號。
雖然版本號必須是 1.0.0
這種格式,但 semver
規範允許設定 pre-release
1.0.0-alpha
。
因此可以將檔案 Hash 作為字尾,並且每個包只有一個檔案。檔名隨意,保留原始副檔名。例如:
https://unpkg.com/[email protected]/index.css
這樣就不用單獨維護每個檔案的版本了,所有檔案都是 0.0.0 版本。如果存在多個內容相同的檔案,它們還可共享同個 URL。
演示
根據上述思路,編寫相應的指令碼 npm-upload.sh。
使用前登陸 NPM。通過 NPM_PKG
環境變數指定包名:
export NPM_PKG=package_name
例如上傳 hello.txt
:
echo "Hello World" > hello.txt ~/npm-upload.sh hello.txt
得到結果:
https://unpkg.com/[email protected]/index.txt
https://cdn.jsdelivr.net/npm/[email protected]/index.txt
可同時上傳多個檔案。例如上傳當前目錄下所有檔案:
~/npm-upload.sh $(find * -type f)
得益於 Hash 的優勢,上傳前指令碼可檢查該檔案是否存在,所以內容相同的檔案不會重複上傳。
應用
如何將網站所有 URL 都對映到 unpkg 或 jsdelivr?一個簡單的辦法是用 <base>
重置根路徑。但這隻適用於相對路徑,並且一次只能選擇一個 CDN。
有沒有辦法自動選擇最快的那個 CDN,並且出現問題後無縫切換到另一個?事實上可通過 Service Worker 實現。案例參考:https://github.com/EtherDream/freecdn/tree/master/examples/free-host