Windows 执行 NODE_ENV=production 报不识别:修正 npm 构建脚本
Windows 把 NODE_ENV=production 当成命令时,区分终端与 npm script-shell,用项目 cross-env 构建入口设置变量,保留 Node 版本与构建依赖安装条件。
在 Windows 终端执行 NODE_ENV=production npm run build,还没进入应用构建就报 NODE_ENV=production 不识别,或提示它不是 cmdlet、函数、脚本文件。这通常是把 POSIX shell 的变量赋值语法用到了 PowerShell 或 cmd。
此时应修正环境变量设置方式。数据库配置、构建缓存和应用依赖是否正常,要等构建命令真正启动后再判断,不能从这条 shell 错误推断应用损坏。
终端类型与 npm 脚本的 shell 可能不同
PowerShell 和 cmd 都不把 NODE_ENV=production 当成这种形式的临时变量赋值。Git Bash、WSL 等 Bash 环境则可能支持它,所以同一台 Windows 机器上换终端会得到不同结果。
npm 脚本默认在 Windows 中使用 cmd,在类 Unix 系统中使用 /bin/sh;项目可以通过 script-shell 改变它。终端外观像 PowerShell,不代表 package.json 中的每条脚本都按 PowerShell 语法解释。
如果项目需要在 Windows、Linux 和 macOS 共用构建脚本,可以把变量设置与构建动作放进一条 cross-env 脚本,避免每个人各写一套 shell 语法。
为构建命令设置变量
先保存当前 package.json、锁文件和 npm 配置。项目没有可直接使用的 cross-env 依赖时,按项目的依赖管理规则加入构建依赖,下面是安装示例:
npm install --save-dev cross-env
核对实际安装版本的 Node 要求。cross-env 8 起要求 Node.js 20 或更高;旧项目不能直接照用当前版本。需要维持 Node 18 或更低的旧构建环境时,cross-env 7 是对应兼容版本,仍应通过项目审批和锁文件固定,而不是忽略 engines 错误。
下面假设已有 build 脚本负责真正构建应用,在 scripts 中新增一个入口。只合并这些键,不要覆盖整份配置:
{
"scripts": {
"build:prod": "cross-env NODE_ENV=production npm run build"
}
}
然后通过 npm 调用:
npm run build:prod
cross-env 将 NODE_ENV 传给后面的构建进程。变量赋值与要运行的命令之间不要插入 &,否则可能变成另一条命令,失去预期的环境传递。也不要把已有 build 改成 npm run build 本身,形成递归调用。
cross-env 是这里的构建工具,放在 devDependencies 的前提是构建阶段确实安装开发依赖。若构建机执行 npm ci --omit=dev,它可能根本不存在。应让受控构建阶段具备所需工具,而不是随手全局安装来掩盖依赖缺口。已经构建好的生产产物可以按部署设计省略开发工具;若运行脚本本身还依赖 cross-env,就必须把这个需求纳入运行环境。
变量已传递,但仍显示 development
shell 错误消失后,应在实际构建进程中确认 process.env.NODE_ENV 的值,再检查应用是否另有环境配置或覆盖逻辑。不要以另一个终端中的变量值证明构建子进程已经收到它,也不要通过系统设置永久改成 production 影响所有项目。
涉及多个带 && 等 shell 运算符的动作时,普通 cross-env 只设置它启动的命令环境;要按项目设计决定是否采用子脚本或 cross-env-shell。单条构建命令无需额外引入 shell 层。
验收分成两步:原 Windows 入口不再把变量赋值当成命令,实际构建进程收到预期值;应用构建结果也符合生产配置。构建过程出现新的依赖或业务错误,再按新错误处理。需要撤回时同时恢复脚本、依赖声明、锁文件及本次 npm 配置,保留已经确认可用的原构建方式。


