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 install | npm ci | npm 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环境变量标识当前钩子名,可在脚本中据此分支逻辑