很遗憾,npm不提供(也没有打算提供)内置功能,允许在npm脚本的中间传递参数(如
此处所述)。参数只能传递到脚本的末尾。
对于Linux和macOS,您可以在npm脚本中使用
bash函数来将参数传递到脚本的中间,就像我的回答
这里一样。但是,Windows会阻塞此类解决方案。
由于跨平台兼容性是一项要求,请考虑将当前位于您的
start
脚本中的逻辑移动到单独的nodejs实用程序脚本中。然后可以通过名为
start
的npm脚本来调用nodejs脚本。
以下描述了如何以跨平台兼容的方式实现您的要求。
1. 自定义nodejs实用程序脚本。
创建一个nodejs脚本,如下所示。我们将脚本命名为start.js,并将其保存在项目目录的根目录中,即package.json文件所在的同一级别。
const execSync = require('child_process').execSync;
const args = process.argv.splice(2, process.argv.length - 2)
.map(arg => arg.replace(/^--/, ''));
execSync(`cross-env ${args.join(' ')} my-app`, {stdio:[0, 1, 2]});
解释:
In the first line we require
nodes builtin execSync()
. We'll utilize this to run cross-env
and set the environment variables.
Nodes builtin process.argv
obtains the arguments passed via the command-line. The first two items in nodes process.argv
are:
- The path to the executable running the JavaScript file.
- The path of the JavaScript file being executed.
However, we're only interested in the elements from the third item in the array onwards - as these will be your arguments passed via the CLI. These lines which read;
const args = process.argv.splice(2, process.argv.length - 2)
.map(arg => arg.replace(/^--/, ''));
create an args
variable and assigns an Array containing each argument passed via the CLI. The first two aforementioned items in point 2 are omitted from the array using the splice()
method. In the map()
method we remove the --
prefix from each argument.
The last line reading:
execSync(`cross-env ${args.join(' ')} my-app`, {stdio:[0, 1, 2]});
invokes cross-env
and places the arguments as a string using Template Literals and the Array join()
method. The stdio
part configures the pipes for stdin
, stdout
, stderr
in the child process.
注意: 如果你的目标是更老版本的node,不支持模板字符串,那么可以使用以下代码替换此行。这将使用+
操作符来处理字符串连接:
execSync('cross-env ' + args.join(' ') + ' my-app', {stdio:[0, 1, 2]});
同样地,如果不支持ES6箭头函数,请将
map()
更改为使用标准函数。例如:
.map(function(arg) {
return arg.replace(/^--/, '');
});
2. package.json脚本。
将package.json中的start
脚本更改为以下内容:
"scripts": {
"start": "node start"
},
这里我们要求Node调用start.js脚本。
注意如果你更喜欢将start.js文件保存在与项目根目录不同的目录位置中,则需要根据需要定义start.js的路径。路径应相对于package.json。例如:
"scripts": {
"start": "node ./the/path/to/start"
},
3. 运行npm脚本
可以通过在命令行中运行npm start
脚本来调用它:
$ npm start -- --env=dev --host=localhost --port=1234
run
部分,即 npm run start ...
在调用 npm 的 start
脚本时不是必需的。