V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
iqoo
V2EX  ›  分享创造

一键上传文件到 NPM 仓库

  •  
  •   iqoo · 2021-10-20 15:24:27 +08:00 · 1877 次点击
    这是一个创建于 1130 天前的主题,其中的信息可能已经有所发展或是发生改变。

    前言

    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/[email protected]/index.js

    unpkg.com/[email protected]/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/[email protected]/index.js

    cdn.jsdelivr.net/npm/[email protected]/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

    第 1 条附言  ·  2021-10-21 11:11:26 +08:00
    更新了下脚本,现在可保留原始扩展名。原文件是 pic.gif 的话最终为 index.gif ,原文件是 hello.txt 最终为 index.txt 。

    不过 unpkg 和 jsdelivr 会将 html 扩展名返回 text/plain 的格式,所以网页文件没用。
    6 条回复    2021-10-20 17:28:37 +08:00
    iqoo
        1
    iqoo  
    OP
       2021-10-20 15:56:51 +08:00
    由于文件名都变成了 index.js ,丢弃了原始扩展名,可能会出现 MIME 相关的问题,脚本稍作修改即可。(用在 Service Worker 的案例中可根据 URL 自动调整 MIME )
    bertonzh
        2
    bertonzh  
       2021-10-20 16:20:32 +08:00
    快进到用 CDN + unpkg 做图床
    bertonzh
        3
    bertonzh  
       2021-10-20 16:21:04 +08:00
    @bertonzh 打错了,NPM + UNPKG
    theprimone
        4
    theprimone  
       2021-10-20 16:46:05 +08:00
    这可太秀了
    mufeng
        5
    mufeng  
       2021-10-20 16:50:03 +08:00
    如果只是为了 cdn 可以直接传到 github, jsdelivr 也是支持的

    https://cdn.jsdelivr.net/gh/iMuFeng/[email protected]/dist/bmdb.js
    iqoo
        6
    iqoo  
    OP
       2021-10-20 17:28:37 +08:00
    @mufeng 同样有缓存的问题,每个文件都要维护相应的版本号才能复用已有缓存
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1532 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 17:19 · PVG 01:19 · LAX 09:19 · JFK 12:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.