# npm script 面试总览:执行环境、编排与依赖确定性

⚡ 30 秒速记

  • npm run xxx = 读 package.json 的 scripts.xxx → 把 node_modules/.bin 加到 PATH 前面 → 交给系统 shell 执行(Linux / Mac 是 sh,Windows 是 cmd.exe)
  • 钩子:prebuild / postbuild 会在 build 前后自动跑
  • 串行用 &&(前一步失败就停),并行用 npm-run-all / concurrently 这类工具,别指望 & 跨平台
  • 给底层命令传参用 --:npm run lint -- --fix;跨平台设环境变量用 cross-env
  • 版本范围管「允许装哪些」,lockfile 管「这次实际装了哪个」;CI 用 npm ci

npm script 本质上就是给命令起别名:npm run build 找到 scripts.build 那段文本,把 node_modules/.bin 加进 PATH,再交给系统 shell 去跑。 所以脚本里能直接写 eslint 而不用写全路径。也正因为交给的是系统 shell,Windows 的 cmd 和 Mac 的 sh 语法不一样,NODE_ENV=production 这种写法在 Windows 上就挂了,要用 cross-env。多个命令串起来用 &&,有一个失败整体就失败。流程一复杂,我会把逻辑挪到一个 scripts/build.mjs 里,package.json 只留入口。

{
  "scripts": {
    "lint": "eslint .",
    "test": "vitest run",
    "verify": "npm run lint && npm test",
    "build": "cross-env NODE_ENV=production node scripts/build.mjs"
  }
}

执行 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 的边界差异。

webapp
公众号
开发者导航
切换夜间模式
点击侧边栏下一篇
折叠侧边栏
收起全部