如何通过npm跨平台运行shell脚本 解决NestJS项目Windows执行失败问题
问题根因
Windows系统原生没有内置sh解释器,直接在npm scripts中调用sh scripts/test.sh会触发找不到命令的报错,无法正常执行。
跨平台实现方案
方案1:直接用cross-env改写(适合脚本逻辑简单的场景)
如果你的test.sh仅用于设置环境变量+执行测试命令,不需要复杂的shell逻辑,直接用cross-env就能实现跨平台,无需保留.sh脚本。
- 安装依赖
npm install cross-env --save-dev
- 重写package.json scripts字段,举个例子:
假设原test.sh内容为:
#!/bin/sh NODE_ENV=test jest --coverage --watchAll=false
直接改写scripts为:
"scripts": { ... "test": "cross-env NODE_ENV=test jest --coverage --watchAll=false", ... }
如果需要在设置环境变量后执行多条命令,可以用cross-env-shell:
"test": "cross-env-shell NODE_ENV=test \"jest --coverage --watchAll=false && echo 测试执行完成\""
方案2:配合shx运行简单shell逻辑
如果你的脚本中有rm、mkdir这类基础shell命令,不想单独改写为Node.js代码,可以用shx做跨平台封装:
- 安装依赖
npm install shx cross-env --save-dev
- 示例:原脚本需要先删除coverage目录再跑测试,直接改写scripts为:
"scripts": { "test": "cross-env NODE_ENV=test shx rm -rf coverage && jest --coverage --watchAll=false" }
方案3:保留.sh脚本的跨平台执行方案
如果你的test.sh逻辑非常复杂,重构成本高,可以借助shelljs实现在Windows上直接执行sh脚本:
- 安装依赖
npm install shelljs cross-env --save-dev
- 新建执行入口
scripts/run-test.js:
const shell = require('shelljs'); const path = require('path'); // 跨平台定位test.sh文件路径 const testShPath = path.resolve(__dirname, './test.sh').replace(/\\/g, '/'); // 执行脚本 const code = shell.exec(`bash ${testShPath}`).code; process.exit(code);
- 重写package.json scripts字段:
"scripts": { "test": "cross-env-shell node scripts/run-test.js" }
方案4:用zx重写脚本(长期维护推荐)
如果你的项目脚本较多,推荐用Google开源的zx工具重写脚本,原生跨平台,语法接近shell,维护成本更低:
- 安装依赖
npm install zx --save-dev
- 新建
scripts/test.mjs,把原sh逻辑迁移过来,示例:
#!/usr/bin/env zx process.env.NODE_ENV = 'test' console.log('开始执行测试') // 删除旧的覆盖率目录 await $`rm -rf ./coverage` // 执行测试 await $`jest --coverage --watchAll=false` console.log('测试执行完成')
- 重写package.json scripts字段:
"scripts": { "test": "zx scripts/test.mjs" }
注意事项
- 所有路径引用统一使用正斜杠
/,不要使用Windows特有的反斜杠\,Node.js生态工具会自动做路径兼容 - 环境变量不要用平台特有的
set(Windows)或export(Unix)命令,统一用cross-env或者在Node.js脚本中给process.env赋值
内容的提问来源于stack exchange,提问作者Алекс Аникей
相关产品推荐
相关产品推荐

