npm 通过 package.json 的 scripts 字段支持内置生命周期钩子(如 prepublishOnly、postinstall)和自定义脚本,需严格匹配命名规则;可组合 &&、npm run --if-present、cross-env 等提升复用性与跨平台兼容性,并通过 .npmrc、环境变量及调试命令优化开发体验。

在 npm 项目中,可以通过 package.json 的 scripts 字段定义自定义生命周期脚本,npm 会自动在特定阶段(如安装、发布、测试前后)触发这些脚本。
理解 npm 内置生命周期钩子
npm 提供了预定义的“生命周期事件”名称(如 preinstall、postinstall、prepublishOnly、posttest 等),只要在 scripts 中声明同名字段,npm 就会在对应阶段自动执行。这些不是随意起名的,必须严格匹配官方命名规则。
-
prepublishOnly:仅在npm publish前运行(推荐替代已弃用的prepublish) -
postinstall:依赖安装完成后执行(常用于构建二进制、生成配置) -
pretest/posttest:分别在npm test前后运行 -
preversion/version/postversion:配合npm version使用,适合自动更新 changelog 或提交版本变更
编写可复用的自定义脚本
除了内置钩子,你还可以定义任意名称的脚本(如 "build:types"、"lint:fix"),然后在其他脚本中通过 npm run xxx 调用。关键在于用好 &&、|| 和 npm run 组合逻辑。
- 用
&&保证顺序执行:"build": "npm run clean && npm run build:js && npm run build:types" - 用
npm run --if-present xxx安全调用(若脚本不存在也不报错) - 用
cross-env设置跨平台环境变量:"dev": "cross-env NODE_ENV=development node server.js"
利用 .npmrc 和环境区分行为
脚本中可通过 process.env.npm_lifecycle_event 获取当前正在执行的 script 名称,便于同一命令在不同上下文做差异化处理。
立即学习“Java免费学习笔记(深入)”;
- 例如在
"prepare"中判断是否为 CI 环境:if [ -n "$CI" ]; then npm run build; fi - 使用
npm config set script-shell bash(或写入.npmrc)可指定 shell,避免 Windows cmd 兼容问题 - 敏感操作(如清理 node_modules)建议加确认提示:
read -p "Confirm clean? (y/N) " -n 1 -r && [[ $REPLY =~ ^[Yy]$ ]] && rm -rf node_modules
调试与验证生命周期执行顺序
运行 npm run prepare --dry-run(或任意脚本)不会真正执行,只打印将要运行的命令链,适合检查钩子是否被正确识别。也可以在脚本中临时加入 echo "Running $npm_lifecycle_event" 输出调试信息。
- 注意:某些钩子(如
prepublishOnly)只在发布时触发,本地npm install不会触发它 -
npm install <pkg>会触发该包自身的postinstall,而非当前项目的 - 想让子依赖也运行钩子?需确保它们的
package.json里也正确定义了对应脚本


















