如果你写的 npm 包只用于内部,不对外公开,可发布到 GitHub 的 npm registry。因为 npm 官方 registry 的免费账号不可以发布私有 package,不想花钱,GitHub 是最好的选择。
发布到 GitHub 的 npm package 如果没有和某个 repo 绑定,默认就是私有的,如果绑定了某个 repo,其可见性将和 repo 保持同步。
发布私有 package 到 GitHub,官方文档有较为详细的说明,但如果对 npm 的理解仅限于 npm install
和 npm uninstall
,官方文档理解起来有难度。所以这篇文章先带大家了解 npm 的相关知识。
当我们使用 npm 安装一个依赖时,npm 会从一个所谓的 registry website 查询并下载数据,默认的 registry 是 https://registry.npmjs.org
,npm 允许你设置其他 registry,其中 GitHub 的 npm registry 是:https://npm.pkg.github.com
。
npm 把 registry 信息记录在 .npmrc
文件,使用 npm login
登录某个 registry 时会自动生成 .npmrc
并往里面写入相关信息,在 macOS 系统该文件位于 ~/.npmrc
。比如我登录了 npm 官方 registry 和 GitHub 的 npm registry 后,~/.npmrc
将包含下面这段信息。每行冒号左边是省略了 https
的 registry 地址,冒号右边对应一个 token,用 _authToken
表示。
//registry.npmjs.org/:_authToken=npm_ohxxxxxxxxxxxxxx
//npm.pkg.github.com/:_authToken=ghp_D8xxxxxxxxxxxxxx
另一个生成 .npmrc
的方法是执行 npm config edit
,该命令会在当前目录生成 .npmrc
文件,并开启编辑器让你修改里面的内容。如果想生成全局配置,需要使用 npm config edit --global
。本地 .npmrc
优先级高于全局的 ~/.npmrc
。
.npmrc
只是 npm 获取配置信息的其中一种方式,我们也可以通过环境变量传入配置信息,或者直接在命令行传入配置信息。
npm gets its config settings from the command line, environment variables, and npmrc files. 出处
根据所在路径的不同,.npmrc
文件其实有四种,执行 npm config list
会展示当前目录下的 npm 配置信息,且会按照来源进行分类,例如 ; "cli" config from command line options
表示接下来的配置来自命令行工具的参数,; "user" config from ~/.npmrc
表示接下来的配置来自 ~/.npmrc
配置文件。
scope
是 npm 另一个重要概念,在 npm 官方 registry 注册一个帐号,你的帐号名就是你的 scope,比如我的 npm 帐号用户名是 kejiweixun
,所以我在 npm 官方 registry 的 scope 就是 @kejiweixun
。
在 npm 官方 registry 发布一个私有 package,必须把这个 package 发布到你的 scope 下,这意味着该 package 的名称必须带有 scope 前缀,例如 @kejiweixun/my-package
。如果是发布公开 package,则没有这个要求。
事实上,凡是名称带有 scope 前缀且是发布到 npm 官方 registry 的 package,首次执行 npm publish
都会默认把它当作私有 package 发布出去,如果要公开发布,需执行:npm publish --access public
。
Private packages always have a scope, and scoped packages are private by default. 出处
正如开头所说,发布到 GitHub 的 package 默认就是私有,和名称是否有 scope 前缀无关。但 GitHub 规定仅支持 scoped package,所以也要在名称前加 scope 前缀,这里的 scope 就是你的 GitHub 用户名。
GitHub Packages only supports scoped npm packages. Scoped packages have names with the format of @owner/name.出处
我们可以在 .npmrc
把一个 scope 和一个 registry 关联起来,关联方法主要有两种:
npm login
登录某个 registry 时,同时提供 scope 参数,例如关联 @kejiweixun
和 GitHub 需要执行:npm login --scope=@kejiweixun --registry=https://npm.pkg.github.com
;~/.npmrc
文件,请看下方例子最后一行,@kejiweixun
位于冒号左边,表示一个 scope,冒号右边是该 scope 所关联的 registry;//registry.npmjs.org/:_authToken=npm_ohxxxxxxxxxxxxxx
//npm.pkg.github.com/:_authToken=ghp_D8xxxxxxxxxxxxxx
@kejiweixun:registry="https://npm.pkg.github.com/"
把 scope 和 registry 关联起来后,当我们 npm publish @my_scope/my-package
,npm 会自动地把这个 package 发布到和 scope 关联的那个 registry,当我们 npm install @my_scope/my-package
,npm 会自动地从和 scope 关联的那个 registry 查询并下载数据。
这就是关联 scope 和 registry 的目的和好处,非常方便。
如果一个 scope 未关联任何 registry,将使用默认 registry:https://registry.npmjs.org
。如果默认 registry 没有你要找的模块,会报错,提示找不到。
--scope
here is a unique identifier for a group of packages as introduced in NPM v2. A scope can be attached to a registry, and so every package published under that scope assumes that same registry. 出处
有了以上基础知识,接下来分享如何发布一个私有 package 到 GitHub 的 npm registry。
write:packages
;npm login --scope=@kejiweixun --registry=https://npm.pkg.github.com --auth-type=legacy
--auth-type=legacy
是 npm 9 才需要添加的参数,--scope=
需要设置为 GitHub 用户名。这种登录方式把 @kejiweixun
这个 scope 绑定到了 GitHub 的 npm registry,登录成功后 ~/.npmrc
将包含如下配置信息,可执行 npm config list
查看:
//npm.pkg.github.com/:_authToken=ghp_D8xxxxxxxxxxxxxx
@kejiweixun:registry="https://npm.pkg.github.com/"
一个较好的做法是,在你的模块所在目录创建一个新的 .npmrc
文件,然后把上述最后一行从 ~/.npmrc
中剪出,粘贴到项目本地的 .npmrc
。这样可避免两个 registry 的 scope 相同时造成的冲突。如果不想创建新的 .npmrc
文件,也可以在命令行添加 --registry
参数,例如发布一个模块时执行:
npm publish --"@kejiweixun:registry=https://npm.pkg.github.com/"
准备一个将要发布的 npm 模块;
打开这个 npm 包的 package.json
文件中,在 name
字段添加 scope 前缀,例如 @kejiweixun/my-package
;
管理版本号,可使用 standard-version
,在 npm 增加一个类似下方的 script:
"scripts": {
"release": "standard-version && git push --follow-tags && npm publish"
}
发布:由于名称带有 scope 前缀,scope 又和 GitHub 的 registry 关联了,所以可以直接使用 npm publish
发布,如果 scope 和 GitHub registry 没有关联,那 npm 会自动把它发布到 npm 的官方 registry,如果你的 npm 用户名不同于 scope 名称,会发布失败;
安装:由于名称带有 scope 前缀,scope 又和 GitHub 的 registry 关联了,所以可以直接执行 npm install
安装,如果 scope 和 GitHub registry 没有关联,那 npm 会从其官方 registry 查找这个 package,可能会提示找不到;
GitHub 有一个独立的 Packages
栏目,这里展示了你发布的所有 package。默认情况下,这些 package 和它所对应的 repo 并不关联在一起。要想把 package 和 repo 关联在一起有两种方法:一是在后台手动关联;二是在 package.json
添加 "repository"
字段,其值设置为 repo 链接,这样发布后就自动关联了,关联后,这个 package 也会展示在 repo 中。
"repository":"https://github.com/OWNER/REPOSITORY",
总结起来其实就三步:
npm login
从而在 ~/.npmrc
添加 GitHub npm registry 的地址和 token;~/.npmrc
或项目所在目录的 .npmrc
或命令行把一个 scope 和 GitHub 的 registry 关联起来;npm publish
;参考文章: