npm 发包流程整理

1. 发布前检查

1.1 package.json 配置检查

发布前需要确保 package.json 配置正确,主要包括以下字段:

  • name:建议使用个人 GitHub 名称 + 发包名称,避免名字冲突(如 @username/package-name
  • version:插件版本,遵循语义化版本规范
  • private:设置为 false,避免仓库被意外发包
  • description:描述插件用途,帮助用户了解包的功能
  • bin:插件安装后的执行来源(如果是命令行工具)
  • files:指定发布时包含的文件,避免发布不必要的文件
  • keywords:指定关键词,方便用户搜索
  • author:指定作者信息
  • license:指定开源协议(如 MIT、Apache-2.0 等)

版本号更新命令

# 更新小版本号(1.0.0 → 1.0.1)
npm version patch

# 更新中版本号(1.0.0 → 1.1.0)
npm version minor

# 更新大版本号(1.0.0 → 2.0.0)
npm version major

配置示例

{
  "name": "@username/package-name",
  "version": "1.0.0",
  "private": false,
  "description": "Package description",
  "main": "dist/index.js",
  "type": "module",
  "packageManager": "pnpm@10.22.0",
  "bin": {
    "package-name": "./dist/index.js"
  },
  "files": ["dist", "README.md"],
  "scripts": {
    "build": "tsup",
    "start": "node dist/index.js",
    "dev": "tsup --watch"
  },
  "keywords": ["keyword1", "keyword2"],
  "author": {
    "name": "Author Name",
    "url": "https://github.com/username"
  },
  "license": "MIT",
  "publishConfig": {
    "access": "public"
  },
  // 按需指定
  "repository": {
    "type": "git",
    "url": "https://github.com/username/repository-name.git"
  },
  "bugs": {
    "url": "https://github.com/username/repository-name/issues"
  },
  "homepage": "https://github.com/username/repository-name#readme"
}

1.2 检查构建产物

发布前需要确认:

  • 检查产物是否已经构建(如 dist 目录是否存在)
  • 检查 README.md 文档是否已经存在且内容完整
  • 确认 files 字段中指定的文件都已准备好

1.3 检查包名可用性

执行以下命令,确认包名是否已被使用:

npm view <包名> 2>&1 | head -5 || echo "包名可用"

如果包名已被占用,需要修改 package.json 中的 name 字段。

2. 发布

2.1 账号登录

执行以下命令完成账号登录:

npm login

如果没有账号,需要先到 npm 官网 注册账号

2.2 手动发布

测试发布:

npm publish --dry-run

执行发布命令:

npm publish

首次发布 scoped package

如果在 package.json 中包名处 name 指定了 @scope/package-name(即代指 @xxx 前缀存在) 这种类型的名称,npm 会默认包为 scoped package

首次发布 scoped package,需要通过 --access public 指定可以被所有用户公开访问:

npm publish --access public

也可以在 package.json 中直接配置,后续不用重复操作:

{
  "publishConfig": {
    "access": "public"
  }
}

发包异常回退

当发布后发现严重 Bug 需要回退时,有以下几种方案:

1. 使用 dist-tag 回退(推荐)

适用场景

  • 发现最新版有严重 Bug
  • 希望用户 npm install xxx 安装到旧版本
  • 不破坏历史发布记录

操作步骤

# 1. 查看当前版本与 tag
npm dist-tag ls your-package-name
# 输出示例:
# latest: 1.2.0
# beta: 1.3.0-beta.1

# 2. 指定旧版本为 latest
npm dist-tag add your-package-name@1.1.5 latest

# 3. 可以移除错误的 tag(可选)
npm dist-tag rm your-package-name latest

优势

  • 官方推荐方案
  • 可回滚、可追溯
  • 对用户影响最小
2. 发布内容回退新版本

适用场景

  • 不想改 tag
  • 语义版本保持正常递增
  • 不能发布与旧版本号相同的版本

注意事项

  • changelog 中应明确说明是 rollback 回退
  • 版本号必须递增(如 1.2.0 → 1.2.1,内容回退到 1.1.5)
3. 强制删除版本(不推荐)

限制条件

  • 发布超过 72 小时的版本不能删除
  • 删除会影响所有依赖该版本的用户
  • 破坏依赖树
  • CI / 生产构建可能直接失败
  • npm 官方明确不推荐

命令

npm unpublish your-package-name@1.2.0

2FA 认证问题

npm 现在要求 2FA(双因素认证)才能发包,但 npm 的 2FA 需要依赖扫描 APP 来完成验证,在某些网络环境下可能无法正常绑定或验证。

image-20251219105417060

解决方案:使用带 2FA 的 Access Token

在 npm 官网生成 Access Token(支持 2FA 认证的 token)

image-20251219095353151

生成 token 后在环境变量或 .npmrc 文件中设置:

# .npmrc 文件
//registry.npmjs.org/:_authToken=your-token

注意

  • 发包时要避免提交 .npmrc 文件到 Git(添加到 .gitignore

GitHub Action 自动化发布

自动化发布可以显著提高开发效率,减少人工操作出现的错误和疏忽。

主要有三种方案:

  • 手动触发 workflow:手动更新版本号,然后在 github 上手动触发 workflow,这种方案和本地发包差不多
  • Git Tag 发布:通过 npm version patch/minor/major 更新本地版本号,执行 git push && git push --tags 推送远端,让 Github Action 获取版本号,执行 npm publish 发布更新
  • semantic-release 全自动发布:基于 commit message 自动决定版本,完全自动化发版

semantic-release 全自动发布

semantic-release 可以协助我们实现全自动发版,下面主要是配置流程。

  • 通过读取提交信息来决定更新的内容版本(patch/minor/major)
  • 支持读取提交信息中的详情,作为更新日志 Release
  • 其他功能,可以参考官方文档拓展 semantic-release 文档
GitHub Secrets 配置
  1. NPM_TOKEN:npm Access Token,即上面提到的 2FA token,用于发布使用
    • 设置位置:GitHub 仓库 Settings → Secrets and variables → Actions → New repository secret → 填写变量和密钥
  2. GITHUB_TOKEN:GitHub Actions 自动提供,无需手动配置
    • 用于创建 GitHub Release,自动注入到 workflow 中
semantic-release 配置

安装相关依赖

npm install --save-dev semantic-release @semantic-release/commit-analyzer @semantic-release/release-notes-generator @semantic-release/changelog @semantic-release/npm @semantic-release/git @semantic-release/github

生成 semantic-release 配置,可以编写在 .releaserc 文件中,也可以在 package.json 中声明

// package.json
"release": {
    "branches": [
      // 指定要触发的分支
      "release"
    ],
    "plugins": [
      "@semantic-release/commit-analyzer",
      "@semantic-release/release-notes-generator",
      [
        "@semantic-release/changelog",
        {
           // 指定日志文件名称
          "changelogFile": "CHANGELOG.md"
        }
      ],
      [
        "@semantic-release/npm",
        {
          // 指定要发布
          "npmPublish": true,
          // 包的根路径
          "pkgRoot": "."
        }
      ],
      [
        "@semantic-release/git",
        {
           // 要提交的资源
          "assets": [
            "package.json",
            "CHANGELOG.md"
          ],
           // 提交 commit 信息,使用当前流程发布版本的 version 和 release notes 作为提交信息
          "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
        }
      ],
      [
        "@semantic-release/github",
        {
           // 以下配置根据团队需求来实现
           // 是否在用户 PR 留下成功发布评论
          "successComment": false,
           // 不改变 PR 标签为 Release 状态
          "releasedLabels": false
        }
      ]
    ]
  }

上面的配置是按声明顺序执行的:

  1. @semantic-release/commit-analyzer:分析 commit message,计算下一个版本号,不会修改文件
  2. @semantic-release/release-notes-generator:根据 commit 生成 release 信息,不会修改文件,只生成文本
  3. @semantic-release/changelog:根据提交信息 commit 生成的 release 自动生成或更新 CHANGELOG.md 文件
  4. @semantic-release/npm:发布 npm 包,修改 package.jsonpackage-lock.json
  5. @semantic-release/git:在 npm 发包后提交 package.jsonCHANGELOG.md 等更新后的文件
  6. @semantic-release/github:发布 github release

编写 Github Action 自动发布脚本

# .github/workflows/ci.yml
name: Release

on:
  push:
    branches:
      - release # 指定 release 分支发布

jobs:
  release:
    name: Release
    runs-on: ubuntu-latest
    steps:
      - name: Checkout # 检出代码
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Node.js # 配置 node 环境
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          registry-url: "https://registry.npmjs.org"

      - name: Install dependencies # 安装依赖
        run: npm install --frozen-lockfile

      - name: Run tests # 执行测试
        run: npm run test

      - name: Build #执行构建操作
        run: npm run build

      - name: Release # 执行 sentiment发布,这里我尝试必须配置在 pacakge.json 中才能执行
        id: release
        uses: cycjimmy/semantic-release-action@v4
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
        with:
          semantic_version: 21

这样就完成整体流程,由于这里没有配置提交触发规则,后续提交时会按照 commit-analyzer 的默认规则去计算版本号

完成测试构建流程 → 检查 commit 信息修改版本号 → 完成日志生成修改日志文件 → 发包后更新文件信息并 Release

feat: xxxxx → minor
fix: xxxxx  → patch
perf: xxxxx → patch
feat!: xxx  → major (因为 `!` 表示 breaking change)

如果有需要可以手动修改

[
  "@semantic-release/commit-analyzer",
  {
    "preset": "angular", // 指定默认风格预设
    "releaseRules": [
      // 覆盖规则
      { "type": "docs", "release": "patch" },
      { "type": "refactor", "release": "minor" }
    ]
  }
]

总结

  • 发布前检查:确保 package.json 配置正确、构建产物完整、包名可用
  • 发布流程:登录账号 → 执行发布命令 → 首次 scoped package 需要 --access public
  • 异常回退:优先使用 dist-tag 回退,避免删除已发布的版本
  • 2FA 认证问题:使用 Access Token 解决 2FA 认证问题,要注意 Token 安全
  • 自动化发布:通过 Git Tag、semantic-release 或手动 workflow 实现自动化发布流程,推荐 semantic-release 流程

参考内容

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值