# npm script 面试总览:执行环境、编排与依赖确定性
⚡ 30 秒速记
npm run name会读取package.json#scripts,在平台 shell 中执行命令,并把node_modules/.bin临时加入PATHpre<name>/post<name>是生命周期钩子;串行用&&,并行要用跨平台工具并正确转发失败码和退出信号- 参数分界用
--,脚本上下文可读取npm_lifecycle_event与npm_package_*,但跨平台环境变量应交给cross-env - 可复现安装依赖靠 lockfile 与
npm ci;版本范围决定允许解析什么,lockfile 记录本次实际解析结果 - 脚本应保持短小、可组合、失败即非零退出;复杂流程迁移到 JavaScript 文件或 CI 配置,别在 JSON 里堆 shell
npm run name 会读取 package.json 的 scripts,把 node_modules/.bin 临时加入 PATH,再交给当前平台的 shell 执行。 串行任务用 && 保证失败即停止,并行工具还要正确处理退出码和终止信号;跨平台环境变量则可交给 cross-env。版本范围约束允许解析的版本,lockfile 记录实际依赖图,持续集成中用 npm ci 校验一致性。流程复杂时,我会把分支和文件处理移到可测试的 Node.js 脚本里。
执行 npm run build 时,npm 先找到脚本文本,再构造包含 node_modules/.bin 的 PATH 并交给当前平台的 shell。因此脚本里能直接写 eslint,无需硬编码 ./node_modules/.bin/eslint;但同一段 shell 在 Windows 与 POSIX 环境的变量语法、引号和命令可用性可能不同,这正是跨平台工具存在的原因。
串行任务用 && 可以保证前一步失败后停止,不能用 ; 假装等价。并行任务不只是“同时启动”:还要聚合退出码、把终止信号发给所有子进程,并避免一个任务失败后另一个继续占端口。规模变大后,把分支、重试和文件处理放进可测试的 Node.js 脚本,package.json 只保留稳定入口。
版本范围和 lockfile 回答的是两个不同问题:^1.2.3 描述未来重新解析时允许选哪些版本,lockfile 固定这次安装使用的精确版本及依赖图。CI 应使用 npm ci,当清单与 lockfile 不一致时直接失败,而不是悄悄重写锁文件。上面的交互演示会真实解析两组 semver 范围,展示 ^1.2.3 与 ^0.2.3 的边界差异。
{
"scripts": {
"lint": "eslint .",
"test": "vitest run",
"verify": "npm run lint && npm test",
"build": "node scripts/build.mjs"
}
}