Win10下Git Bash执行Yarn递归命令报错排查
问题:Git Bash中Yarn递归脚本执行报错,展开命令却正常
问题背景
在Windows 10系统的Git Bash环境下,执行项目中的Yarn递归命令(如yarn build)时,会抛出「命令语法不正确」的错误,但将脚本中的命令全部展开后直接在Git Bash中执行,却能正常运行。现咨询该问题是Git Bash已知Bug还是配置问题。
报错日志
$ yarn build yarn run v1.22.10 $ yarn lint && rm -rf dist/test && yarn build:cjs && yarn build:umd:min $ eslint .eslintrc.json --fix --color --cache --max-warnings=0 ./src $ rm -rf dist/cjs && tsc src/index.ts --downlevelIteration --declaration --module commonjs --target es5 --outDir dist/cjs $ yarn build:umd && uglifyjs --compress --mangle --source-map --ie8 --comments -o dist/umd/js-sdsl.min.js -- dist/umd/js-sdsl.js $ yarn build:esm && rm -rf dist/umd && mkdir dist/umd && rollup dist/esm/index.js --format umd --name sdsl -o dist/umd/js-sdsl.js $ rm -rf dist/esm && tsc src/index.ts --downlevelIteration --declaration --module es2015 --target es5 --outDir dist/esm 命令语法不正确。 error Command failed with exit code 1. error Command failed with exit code 1. error Command failed with exit code 1.
package.json脚本配置
{ "scripts": { "setup": "rm -rf node_modules && yarn", "build": "yarn lint && rm -rf dist/test && yarn build:cjs && yarn build:umd:min", "build:cjs": "rm -rf dist/cjs && tsc src/index.ts --downlevelIteration --declaration --module commonjs --target es5 --outDir dist/cjs", "build:esm": "rm -rf dist/esm && tsc src/index.ts --downlevelIteration --declaration --module es2015 --target es5 --outDir dist/esm", "build:umd": "yarn build:esm && rm -rf dist/umd && mkdir dist/umd && rollup dist/esm/index.js --format umd --name sdsl -o dist/umd/js-sdsl.js", "build:umd:min": "yarn build:umd && uglifyjs --compress --mangle --source-map --ie8 --comments -o dist/umd/js-sdsl.min.js -- dist/umd/js-sdsl.js", "test": "rm -rf dist/test && tsc --downlevelIteration --declaration src/test.ts --module commonjs --target es5 --outDir dist/test && node ./dist/test/test.js", "lint": "eslint .eslintrc.json --fix --color --cache --max-warnings=0 ./src", "deploy": "yarn build:umd:min && typedoc src/type.ts && mv dist/umd/* docs && gh-pages -d docs" } }
展开命令执行成功日志
$ yarn lint && rm -rf dist/test && rm -rf dist/cjs && tsc src/index.ts --downlevelIteration --declaration --module commonjs --target es5 --outDir dist/cjs && rm -rf dist/esm && tsc src/index.ts --downlevelIteration --declaration --module es2015 --target es5 --outDir dist/esm && rm -rf dist/umd && mkdir dist/umd && rollup dist/esm/index.js --format umd --name sdsl -o dist/umd/js-sdsl.js && uglifyjs --compress --mangle --source-map --ie8 --comments -o dist/umd/js-sdsl.min.js -- dist/umd/js-sdsl.js yarn run v1.22.10 $ eslint .eslintrc.json --fix --color --cache --max-warnings=0 ./src Done in 21.30s. dist/esm/index.js → dist/umd/js-sdsl.js... (!) `this` has been rewritten to `undefined` dist\esm\Vector\Vector.js 1: var __generator = (this && this.__generator) || function (thisArg, body) { ^ 2: var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 3: return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; ...and 7 other occurrences dist\esm\Deque\Deque.js 1: var __generator = (this && this.__generator) || function (thisArg, body) { ^ 2: var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 3: return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; ...and 1 other occurrence dist\esm\LinkList\LinkList.js 1: var __generator = (this && this.__generator) || function (thisArg, body) { ^ 2: var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; 3: return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; ...and 1 other occurrence ...and 4 other files created dist/umd/js-sdsl.js in 558ms
问题分析与解决方向
这不是Git Bash的已知Bug,而是Windows环境下Yarn执行嵌套脚本时的shell兼容性问题:
- Yarn在Windows默认会调用
cmd.exe执行脚本,而非Git Bash的bash解释器,导致bash风格的命令(如rm -rf、&&链式调用)在递归执行时被cmd解析出错。 - 直接展开命令在Git Bash中执行时,命令由bash解释,所以正常;但通过Yarn递归调用脚本时,子脚本可能被切换到cmd环境执行。
解决办法
- 指定Yarn使用bash执行脚本:执行命令时添加环境变量,如
YARN_SHELL="C:\\Program Files\\Git\\bin\\bash.exe" yarn build;或者在项目根目录创建.yarnrc文件,写入shell "C:\\Program Files\\Git\\bin\\bash.exe"(路径需根据你的Git安装位置调整)。 - 替换bash命令为跨平台命令:用
rimraf替代rm -rf,mkdirp替代mkdir,避免依赖bash特定命令。安装依赖:yarn add rimraf mkdirp --dev,修改后的脚本示例:"build:cjs": "rimraf dist/cjs && tsc src/index.ts --downlevelIteration --declaration --module commonjs --target es5 --outDir dist/cjs", "build:umd": "yarn build:esm && rimraf dist/umd && mkdirp dist/umd && rollup dist/esm/index.js --format umd --name sdsl -o dist/umd/js-sdsl.js" - 避免Yarn递归调用:将嵌套的脚本命令直接合并到主脚本中,就像手动展开的那样,减少Yarn子进程切换shell的概率。
内容的提问来源于stack exchange,提问作者Zilong Yao
相关产品推荐
相关产品推荐

