unpkg 、jsdelivr 等站点可加速 NPM 包文件,适合作为个人网站或演示案例的免费 CDN 。
虽然上传文件到 NPM 很简单,创建 package.json
然后 npm publish
即可,但之后更新却很麻烦 —— 即使只更新一个文件,也要发一个新版本的包。由于 URL 包含版本号,因此所有文件的 URL 都会变化,导致无法利用缓存。
当然也可以增量发布,每次只发布变化的文件,从而充分利用已有的文件。但这需记录每个文件的状态,实现起来较为麻烦。
这里讲解一种更巧妙的方案 —— 使用文件 Hash 作为版本号。
虽然版本号必须是 1.0.0
这种格式,但 semver
允许设置 pre-release
后缀,例如 1.0.0-alpha
。
因此可以将文件 Hash 作为后缀,并且每个包只有一个文件。文件名随意,尽量使用文本格式的扩展名,从而能被 CDN 压缩传输。例如:
unpkg.com/free-host@0.0.0-1lZrk8wvUYweiDaC/index.js
unpkg.com/free-host@0.0.0-L4HFRlSKt3ggTXAK/index.js
这样就不用单独维护每个文件的版本了,所有文件都是 0.0.0 版本。如果存在多个内容相同的文件,它们还可共享同个 URL 。
脚本 npm-upload.sh
:
gist.github.com/EtherDream/f9f01a2bc73d055f8f861eca29e83b8a
使用前登陆 NPM 。通过 NPM_PKG
环境变量指定包名:
export NPM_PKG=package_name
例如上传 hello.html
:
echo "<h1>Hello World</h1>" > hello.html
~/npm-upload.sh hello.html
得到结果:
unpkg.com/free-host@0.0.0-bq5bQezSnp9gY66v/index.js
cdn.jsdelivr.net/npm/free-host@0.0.0-bq5bQezSnp9gY66v/index.js
可同时上传多个文件。例如上传当前目录下所有文件:
~/npm-upload.sh $(find * -type f)
得益于 Hash 的优势,上传前脚本可检查该文件是否存在,所以内容相同的文件不会重复上传。
如何将网站所有 URL 都映射到 unpkg 或 jsdelivr ?一个简单的办法是用 <base>
重置根路径。但这只适用于相对路径,并且一次只能选择一个 CDN 。
有没有办法自动选择最快的那个 CDN,并且出现问题后无缝切换到另一个?事实上可通过 Service Worker 实现。案例参考:github.com/EtherDream/freecdn/tree/master/examples/free-host
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.