1. 基本概念
npm run 用于执行在 package.json 文件的 scripts 字段中定义的脚本命令。
javascript
{
"name": "my-project",
"version": "1.0.0",
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"test": "jest",
"build": "webpack --mode=production"
}
}
2. 工作流程详解
2.1 命令解析阶段
bash
npm run script-name
-
npm 解析命令,提取脚本名称
-
查找当前项目的
package.json文件
2.2 脚本查找过程
# npm 内部查找逻辑
1. 检查 package.json 中的 scripts 字段
2. 如果找到对应脚本,准备执行环境
3. 如果未找到,检查预定义脚本(start, test 等)
4. 如果都不存在,报错退出
2.3 环境准备阶段
# npm 会做以下准备工作:
- 创建子进程执行环境
- 设置 NODE_ENV 环境变量(如果未设置)
- 将 ./node_modules/.bin 添加到 PATH 环境变量开头
- 设置进程特定的环境变量
3. PATH 环境变量处理
这是 npm run 最重要的特性之一:
执行前 PATH 示例: /usr/local/bin:/usr/bin:/bin # 执行时 PATH 变为: ./node_modules/.bin:/usr/local/bin:/usr/bin:/bin
这意味着:
-
本地安装的依赖包中的可执行文件可以直接使用
-
不需要全局安装工具(如 webpack、jest 等)
4. 生命周期脚本
npm 支持自动执行的生命周期脚本:
javascript
{
"scripts": {
"prestart": "echo '准备启动...'",
"start": "node server.js",
"poststart": "echo '启动完成!'",
"pretest": "echo '准备测试...'",
"test": "jest",
"posttest": "echo '测试完成!'"
}
}
执行 npm run test 时的顺序:
bash
prestart → start → poststart
5. 环境变量传递
5.1 内置环境变量
javascript
// 在脚本中可以访问的环境变量:
process.env.npm_package_name // 包名
process.env.npm_package_version // 版本号
process.env.npm_package_scripts_build // build脚本内容
process.env.NODE_ENV // 环境变量
5.2 自定义环境变量
javascript
# 设置环境变量执行脚本
NODE_ENV=production npm run build
# 或者在 package.json 中
{
"scripts": {
"build:prod": "NODE_ENV=production webpack"
}
}
6. 参数传递
6.1 向脚本传递参数
bash
npm run script-name -- --arg1 value1 --arg2 value2
示例:
javascript
{
"scripts": {
"serve": "webpack serve"
}
}
bash
npm run serve -- --port 8080 --host 0.0.0.0
# 实际执行: webpack serve --port 8080 --host 0.0.0.0
6.2 在脚本中使用参数
javascript
{
"scripts": {
"deploy": "node deploy.js",
"deploy:env": "node deploy.js --env $npm_config_env"
}
}
bash
npm run deploy:env --env=production
7. 实际工作流程示例
7.1 完整执行流程
bash
# 用户输入
npm run dev
# npm 内部执行流程:
1. 读取 package.json
2. 找到 scripts.dev = "nodemon server.js"
3. 检查是否有 predev 脚本并执行
4. 将 ./node_modules/.bin 添加到 PATH
5. 创建子进程执行 "nodemon server.js"
6. 检查是否有 postdev 脚本并执行
7. 返回执行结果
7.2 复杂脚本示例
javascript
{
"scripts": {
"prebuild": "rimraf dist && mkdirp dist",
"build": "webpack --mode=production",
"postbuild": "node ./scripts/notify.js",
"dev": "concurrently \"npm run server\" \"npm run client\"",
"server": "nodemon server.js",
"client": "webpack serve --hot"
}
}
8. 高级特性
8.1 跨平台兼容性
javascript
{
"scripts": {
"clean": "rm -rf dist", // Unix 系统
"clean:win": "rmdir /s /q dist", // Windows 系统
"clean:cross": "rimraf dist" // 跨平台解决方案
}
}
8.2 条件执行
javascript
{
"scripts": {
"build": "webpack",
"build:analyze": "npm run build -- --analyze",
"deploy": "npm run build && npm run test && node deploy.js"
}
}
8.3 使用工具函数
javascript
{
"scripts": {
"setup": "npm install && npm run build && npm run test",
"reset": "npm run clean && npm install && npm run build",
"ci": "npm ci && npm run test:coverage"
}
}
9. 调试和排查
9.1 查看可用脚本
bash
npm run
# 或
npm run --silent
9.2 调试脚本执行
bash
# 查看实际执行的命令
npm run build --dry-run
# 显示详细日志
npm run build --loglevel verbose
9.3 错误处理
bash
{
"scripts": {
"build": "webpack || echo '构建失败'",
"test": "jest --passWithNoTests",
"deploy": "npm run build && npm run test && node deploy.js"
}
}
总结
npm run 的工作机制可以概括为:
-
解析阶段:读取 package.json 中的 scripts 配置
-
准备阶段:设置环境变量,修改 PATH
-
执行阶段:按顺序执行生命周期脚本
-
清理阶段:返回执行结果,恢复环境