在本地和CI/CD中支持npm免登录发布

本节涉及的内容源码可在vue-pro-components c8 分支[1]找到,欢迎 star 支持!

前言

本文是 基于Vite+AntDesignVue打造业务组件库[2] 专栏第 9 篇文章【在本地和CI/CD中支持npm免登录发布】,专门分享一下如何在 npm 发包时支持免登录发布,并同时支持在本地和CI/CD中操作发布流程。

在组件库技术选型和开发环境搭建[3]这篇文章中,我们简单介绍了怎么把一个包发布到 npm 上,但是执行lerna publish之前需要先验证登录,因为lerna publish它背后执行的还是npm publish,所以首先需要通过 npm 的认证流程。

7da3ad77219864c94f86b2ab2cf2335e.png

一个流程中如果要执行登录流程,那么它的自动化程度就不会很高。如何解决这个问题呢?答案是 token,只要我们把 token 通过某个配置告诉 npm,就等同于告诉 npm 我是谁,所以只要这个 token 代表的是我的身份,自然就没必要输入账户密码登录了。

创建 token

我们先在 npm 网站[4] 中登录,在用户下拉菜单这里能找到创建 token 的入口。

00b582200531489eccaeeabae98b8637.png

token 有两种,

fb90cee92a0b0182a86f7f557ef79031.png

一种是经典的通用 token,就是不限制使用范围,你名下的任何包/组织都能用这个 token 去管理。但是也大概分几种类型。如果要用在自动化流程中,需要避开双因素(2FA)验证,我们就创建 Automation 类型的 token。

6110b83a3ed54029c26d74d2eb60d7a4.png

还有一种就是更细粒度的 token,可以把权限控制到过期时间/IP范围/可读可写/包/组织等。

4596327c2f0a444ca92dbf14bde973a7.png

如果你觉得用界面操作很 Low,也可以选择极客风的命令行。npm 提供了创建 token 的命令行,具体见 npm token[5]

怎么使用 token?

我们创建 token 主要是为了用于发布 npm 包。这个 token 我们可以配置在.npmrc文件中,对应的 key 是_authToken

faa3095820c46e6635721626f6f5f833.png
//registry.npmjs.org/:always-auth=true
//registry.npmjs.org/:_authToken=your npm token

但是.npmrc文件一般是要提交到仓库中的,而 token 又是一个比较私密的数据,就不适合写死放在 .npmrc 中,此时我们可以使用变量替代,改成这样:

//registry.npmjs.org/:always-auth=true
//registry.npmjs.org/:_authToken=${NPM_TOKEN}

那么这个变量可以从哪里读来呢?我们可以看看 npm 的一篇文档Set the token as an environment variable on the CI/CD server[6]是怎么说的。

The npm cli will replace this value with the contents of the NPM_TOKEN environment variable.

答案是环境变量。这里要考虑 2 种情况,一个是本地化发布,一个是在 CI/CD 中发布。

首先说后面一种情况,在 CI/CD 中发布 npm 包已经有比较标准的方案了,大部分 CI/CD 平台都支持在 yaml 配置文件中指定环境变量,并且支持加密,没有暴露 token 的风险。上述文档中也有提到,关键配置如下:

steps:
  - run: |
      npm install
  - env:
      NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

那么关键还是在于前面那种情况,有时候需要在本地发布 npm 包,此时应该怎么办呢?

我首先尝试添加系统环境变量,但是没有立即成功;

51ae260c9929afd7d6fc7b3b42199527.png

我还尝试了dotenv,虽然dotenv能加载.env文件到环境变量中,不过也不太方便。

如果.npmrc中存在变量NPM_TOKEN,跑任何npm scripts,都会去寻找${NPM_TOKEN},如果找不到就会报错,而我们不可能给所有脚本都加上dotenv

所以如果要在本地发布,一个替代方法是临时手动将.npmrc的 token 写死,改成:

//registry.npmjs.org/:_authToken=npm_xxxxxxxxxxxxxxxxxx

但是执行 lerna publish 的时候又需要一个干净的 git 状态,如果有 modified files 也不行(因为临时改了 .npmrc 就会导致 git 工作区不干净了)。啊,真难!最理想的办法还是把环境变量给搞定,同时又不能改太多脚本。

最后我发现加系统环境变量其实是有用的,关键是改了后要重新打开 VSCode(之前没有尝试这一步,导致我以为加系统环境变量没有用),否则终端加载不到最新的环境变量,果然还得是重启大法!所以最佳选择是使用变量${NPM_TOKEN}

本地验证 token 是否生效

搞定了环境变量后,我们先试试本地 publish 的场景。

考虑到之前用npm login或者npm adduser登录过,所以我们需要先退出登录再测试,否则无法确定是否 token 是否真的起了作用。

退出登录命令:

npm logout --registry=https://registry.npmjs.org

接着可以试试lerna publish或者npm publish,经测试已经不需要登录就能发布 npm 包了。

8cbcd8a20d61dd38ab989ed88caf22a4.png

集成构建和发布流程

在集成构建和发布流程之前,我们参照@vue-pro-components/utils的构建流程把@vue-pro-components/headless的构建流程搞定,因为它们本质上都是函数库,打包过程不会有太多差异,抄一抄它不香吗?

4b8c07b68d63c2a1f91736e2ee31145a.png

同时根据各个包之间的依赖关系,新增一个统一构建的入口buildBatch,这样就能通过gulp buildBatch一条命令把所有的构建工作都做了。

继而可以得到一条集成构建和发布流程的命令release

"release": "yarn buildBatch && yarn publish:package",

所以只要我们把代码修改完毕,版本号确定之后,就可以执行yarn release进行发布了。

CI/CD workflow 搭建

Github 本身也支持 CI/CD,相关的产品是 Github Actions,所以我们可以直接使用它实现自动化构建和发布流程。

现在市面上有很多 CI/CD 工具,它们虽然在配置上有些差异,但是架构和理念都是相似的,学会使用一个,其他的参考着文档也基本能看得懂。

使用 Github Actions 主要就是写配置文件,我们可以基于官方的一些模板[7]来初始化一个配置文件,这个 Publish Node.js Package 模板就比较合适。

6fc122ad8d89f3d59d1d23b65ddd9bae.png

你也可以通过阅读Github Actions 文档[8]来了解更多相关知识。

我们按照模板文件改一改:

# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
name: Build and Publish Node.js Package

on:
  push:
    branches:
    - c*

env:
  NPM_TOKEN: ${{secrets.NPM_TOKEN}}

jobs:
  publish-npm:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      
      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: 16
            
      - name: Install Dependency
        run: yarn install --frozen-lockfile
        
      - name: Build and Publish
        run: yarn release

因为这里要用到NPM_TOKEN变量,我们先到 Settings -> Secrets 中维护好变量。

6e958dbb10a40657e17e2720748c4269.png

修改一个版本号测试一下,一个简单版本的 CI/CD 这不就有了吗?

6341b6499f08c7da294d91dd44eb49e8.png

然后可以再加个 Cache 优化一下安装依赖的过程,这可以用到actions/cache@v3[9]

结语

通过阅读和学习本文内容,我们已经能掌握怎么优雅地发布一个 npm 包,并同时支持了在本地和远程 CI/CD 中进行发布操作。但是我们应该注意到,每次发布都会执行完整的buildBatch过程,这个有没有必要呢?我想有时候是没有必要的,因为有可能某一个包根本就没修改过,但是每次发布时都执行打包过程就会浪费资源和时间。这里先留个疑问,后面文章接着讲。如果您对我的专栏感兴趣,欢迎您订阅关注本专栏[10],接下来可以一同探讨和交流组件库开发过程中遇到的问题。

参考资料

[1]

vue-pro-components c8 分支: https://github.com/cumt-robin/vue-pro-components/tree/c8

[2]

基于Vite+AntDesignVue打造业务组件库: https://juejin.cn/column/7140103979697963045

[3]

组件库技术选型和开发环境搭建: https://juejin.cn/post/7153432538046791687#heading-16

[4]

npm 网站: https://www.npmjs.com/

[5]

npm token: https://docs.npmjs.com/cli/v9/commands/npm-token

[6]

Set the token as an environment variable on the CI/CD server: https://docs.npmjs.com/using-private-packages-in-a-ci-cd-workflow#set-the-token-as-an-environment-variable-on-the-cicd-server

[7]

官方的一些模板: https://github.com/cumt-robin/vue-pro-components/actions/new

[8]

Github Actions 文档: https://docs.github.com/en/actions/quickstart

[9]

actions/cache@v3: https://github.com/actions/cache/blob/main/examples.md#node---yarn

[10]

订阅关注本专栏: https://juejin.cn/column/7140103979697963045

END

d77c86914ebbf90a30fb5b99c43d823e.png

如果觉得这篇文章还不错

点击下面卡片关注我

来个【分享、点赞、在看】三连支持一下吧22a6e8da9a7898d0b340221eb24bf753.png

   “分享、点赞、在看” 支持一波 72de03a5484eba2577dfb9cf8daad02c.png 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值