全部学科
Python全栈
python
NodeJS全栈
nodejs
📅 2026-05-25 6 分钟 ✍️ juanwangdev

npm完整生命周期流程

NPM 生命周期钩子贯穿包的发布、安装、卸载全过程,理解完整流程才能精准控制每个环节。

完整生命周期流程

发布流程生命周期

Bash
prepublish → prepare → prepublishOnly → prepack → pack → postpack → publish → postpublish
JSON
# 执行 npm publish 时的完整顺序
# 1. prepublish       - 发布前准备(已废弃语义,仍广泛使用)
# 2. prepare          - 安装/发布前都执行,用于编译构建
# 3. prepublishOnly   - 仅 npm publish 时执行(不受 npm install 触发)
# 4. prepack          - 打包 tarball 前
# 5. pack             - 打包中(npm pack 时也触发)
# 6. postpack         - 打包完成后,可修改 tarball
# 7. publish          - 发布到 registry 时
# 8. postpublish      - 发布完成后(通知、清理等)

安装流程生命周期

JSON
preinstall → install → postinstall
JSON
// 被安装的包的 package.json
{
  "scripts": {
    "preinstall": "node preinstall.js",
    "install": "node-gyp rebuild",
    "postinstall": "node postinstall.js"
  }
}
  • preinstall:安装前检查环境
  • install:编译原生模块(如 node-gyp)
  • postinstall:初始化配置、生成文件

安装脚本以当前用户权限执行,存在安全风险。生产环境可用 --ignore-scripts 禁用。

卸载流程生命周期

Bash
preuninstall → uninstall → postuninstall
JSON
{
  "scripts": {
    "preuninstall": "node cleanup.js",
    "postuninstall": "node remove-config.js"
  }
}
  • preuninstall:卸载前清理运行时资源
  • postuninstall:卸载后移除配置文件、缓存

启动与测试生命周期

Bash
# npm start
prestart → start → poststart

# npm test
pretest → test → posttest

# npm restart
prerestart → restart → postrestart
# 若未定义 restart,默认执行: stop → start
Bash
{
  "scripts": {
    "pretest": "npm run lint",
    "test": "jest --coverage",
    "posttest": "npm run report-coverage"
  }
}

版本变更生命周期

text
preversion → version → postversion
text
# 执行 npm version patch 时的顺序
# 1. preversion  - 版本变更前(运行测试,确保代码状态正常)
# 2. version     - 版本号已更新,提交前(生成 CHANGELOG 等)
# 3. postversion - 提交和标签完成后(推送到远程仓库)
text
{
  "scripts": {
    "preversion": "npm test",
    "version": "npm run changelog && git add CHANGELOG.md",
    "postversion": "git push && git push --tags"
  }
}

preversion 失败会中止版本变更,是发布前的最后质量关卡。

生命周期执行规则

规则说明
前缀 pre主脚本前执行,失败则中止主脚本
前缀 post主脚本后执行,主脚本失败则不执行
串行执行同一命令的 pre → 主 → post 严格串行
环境变量npm_lifecycle_event 存储当前脚本名
text
# 在脚本中判断当前生命周期
echo $npm_lifecycle_event  # 输出: postinstall
text
# 跨平台获取(Windows 兼容)
node -e "console.log(process.env.npm_lifecycle_event)"

生命周期与依赖类型的关系

钩子npm installnpm cinpm install --production
自身 pre/postinstall执行执行执行
依赖 pre/postinstall执行执行仅生产依赖
prepare执行执行执行

npm ci 同样触发安装脚本。Docker 构建中建议 npm ci --ignore-scripts 后手动执行必要脚本。

要点总结

  • 发布流程 8 个钩子按序执行:prepublish → prepare → prepublishOnly → prepack → pack → postpack → publish → postpublish
  • 安装流程 3 个钩子:preinstall → install → postinstall,是恶意代码注入的主要入口
  • pre 钩子失败会中止后续执行,post 钩子仅在前序成功时触发
  • 版本变更钩子 preversion → version → postversion 是自动化发布的核心
  • npm_lifecycle_event 环境变量标识当前钩子名,可在脚本中据此分支逻辑
想在手机上练习这篇文章的配套题目?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码
← 上一篇 npm workspaces与Monorepo管理
下一篇 → prepare与prepublishOnly钩子
扫码体验小程序
加载中
想在手机上刷题学习?
使用微信卷王开发者小程序,打开首页顶部扫码功能识别二维码