学习记录-package.json的scripts添加参数的方式有那些
一、最基础:通过命令行传参(--)
最常见的写法:
"scripts": {"start": "node app.js"
}
执行:
npm run start -- --port=3000 --mode=dev
这里的 -- 是关键,告诉 npm:
“后面的参数不要当 npm 自己的参数解析,直接传给 script 命令”
第一个
--是必须的,它告诉 npm 将后续的参数传递给脚本。第二个
--是可选的,主要用于明确区分位置参数和选项参数,尤其在 Node.js 脚本中使用process.argv或parseArgs等方法解析参数时。如果传位置参数记得在parseArgs的allowPositionals参数配置为true,不然会报异常。
const {values:{format}} = parseArgs({// allowPositionals:true,args: process.argv.slice(2),//一个字符串数组,表示要解析的参数。默认情况下,它会移除 process.argv 中的 execPath 和 filename。options: {//一个对象,用于描述已知的参数。键是选项的长名称,值是一个对象,包含 type、multiple、short 和 default 等属性。format: {//声明script命令参数,不声明,未知参数会报错type: "string",short:'f',//别名default: "esm",//默认没有传则取esm}}
})📜 在 Node.js 中获取
console.log(process.argv)
// 输出:['node', 'app.js', '--port=3000', '--mode=dev']console.log(process.argv.slice(2))
// 输出:['--port=3000', '--mode=dev']
或者使用 Node 18+ 的 parseArgs:
import { parseArgs } from 'node:util'
const args = parseArgs({options: {port: { type: 'string' },mode: { type: 'string' }}
})
console.log(args.values) // { port: '3000', mode: 'dev' }
⚠️ 注意兼容性(npm vs pnpm vs yarn)
| 工具 | 需要 -- 吗 | 说明 |
|---|---|---|
| npm | ✅ 需要 | npm run start -- --port=3000 |
| pnpm | ✅ 需要 | pnpm run start -- --port=3000 |
| yarn v1 | ❌ 可直接 | yarn start --port=3000 |
| yarn v2+ | ✅ 建议加 -- | 与 npm 对齐 |
二、通过环境变量传参(推荐跨平台)
"scripts": {"dev": "cross-env PORT=3000 HOST=127.0.0.1 node app.js"
}
执行:
npm run dev
📜 在 Node.js 中获取
console.log(process.env.PORT) // 3000
console.log(process.env.HOST) // 127.0.0.1
优点:
不依赖参数解析;
跨平台(Windows/macOS/Linux 都支持);
常用于配置环境(如
NODE_ENV=production)。
⚠️ 注意:
直接写
PORT=3000只在 Linux/macOS 生效;Windows 需要
cross-env工具来统一写法。
三、通过 npm 的环境变量机制(npm_config_xxx)
这是 npm/pnpm 的“隐藏功能”之一。
当你传入:
npm run build -- --port=3000
npm 会自动创建环境变量:
process.env.npm_config_port === '3000'
所以即使脚本没解析参数,也可以直接用:
✅ 你甚至可以直接在 scripts 中取:
"scripts": {"info": "echo Port: $npm_config_port"
}
执行:
npm run info --port=5000
# 输出 Port: 5000
✅ 优点:
无需额外依赖;
跨平台支持;
适合简单参数传递(比如构建端口、目标环境)。
⚠️ 缺点:
不能嵌套结构;
参数名必须是合法的 JS 变量名(
--port✅,--my-port❌)。
四、通过 Node 脚本读取 .env 文件
这是现代项目最常见的方式之一(Vite、Vue CLI、Next.js 都这样做)。
1️⃣ 安装 dotenv
pnpm add dotenv -D
2️⃣ 新建 .env 文件
PORT=3000
HOST=127.0.0.1
NODE_ENV=development
3️⃣ 在脚本中加载
import dotenv from 'dotenv'
dotenv.config()console.log(process.env.PORT)
console.log(process.env.HOST)
✅ 优点:
适合多环境(
.env.development,.env.production)构建系统普遍支持;
可与
cross-env组合。
五、通过 npm lifecycle hooks(生命周期变量)
当你运行 npm run dev 时,npm 会自动注入一些变量,比如:
| 环境变量 | 示例值 |
|---|---|
npm_lifecycle_event | dev |
npm_package_name | my-app |
npm_package_version | 1.0.0 |
可以直接在脚本中使用:
console.log(process.env.npm_lifecycle_event) // "dev"
或者在命令里用:
"scripts": {"dev": "echo current: $npm_lifecycle_event"
}
六、组合方式(最常见于脚手架)
你可以把多种方式一起用:
"scripts": {"dev": "cross-env NODE_ENV=development node scripts/dev.js -- --port=3000"
}
在 scripts/dev.js 中:
import { parseArgs } from 'node:util'
console.log(process.env.NODE_ENV) // "development"const args = parseArgs({options: { port: { type: 'string' } }
})
console.log(args.values.port) // "3000"
✅ 优点:
NODE_ENV控制运行环境;命令行参数控制动态选项;
双保险方案,现代 CLI 都这么干。
七、总结对照表
| 传参方式 | 示例命令 | 脚本获取方式 | 特点 |
|---|---|---|---|
| 命令行参数 | npm run start -- --port=3000 | process.argv / parseArgs() | 灵活,需解析 |
| 环境变量(cross-env) | cross-env PORT=3000 node app.js | process.env.PORT | 跨平台,推荐 |
| npm_config 参数 | npm run build -- --port=3000 | process.env.npm_config_port | 无需解析,简洁 |
| dotenv 文件 | .env 中定义 | dotenv.config() + process.env.xxx | 配置化管理 |
| npm 生命周期变量 | 自动注入 | process.env.npm_lifecycle_event | 可获取当前执行命令名 |
实战建议(通用推荐)
| 场景 | 推荐方案 |
|---|---|
| 开发 / 构建环境区分 | cross-env NODE_ENV=xxx |
| 传临时参数(如端口) | npm run dev -- --port=3000 |
| 稳定配置 | .env 文件 + dotenv |
| CLI 工具开发 | process.argv + parseArgs |
| 简单脚本 | process.env.npm_config_xxx |
