将环境变量作为参数传递给 npm 脚本的跨平台方式
Cross-platform way to pass environment variables as arguments to npm scripts
从 Windows 或 Linux,我想要一种将 args 传递给 npm script
的方法,但要将它们作为环境变量注入
在命令行中,我将以这种方式开始我的项目:
npm run start -- --env=dev --host=localhost --port=1234
为了使用我的 cli 参数并将它们作为 env 变量注入而不考虑平台,我使用了 cross-env npm 包:
package.json
"scripts": {
"start": "cross-env env=%env% host=%host% port=%port% my-app"
},
我知道上面的语法无效,但是 start
脚本能以某种方式使用我传递的参数而不是将它们转发给 my-app
吗?
不幸的是,npm 没有,也不打算提供允许将参数传递到 npm 脚本中间的内置功能(如所述here) .参数只能传递到脚本的末尾。
对于 Linux 和 macOS,您可以使用 bash functions in npm-scripts to pass arguments to the middle of a script, as per my answer 。然而 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]});
解释:
在第一行我们 require
个节点内置 execSync()
。我们将利用它 运行 cross-env
并设置环境变量。
Nodes builtin process.argv
获取通过命令行传递的参数。节点 process.argv
中的前两项是:
- 可执行文件 运行 到 JavaScript 文件的路径。
- 正在执行的JavaScript文件的路径。
但是,我们只对数组中第三项以后的元素感兴趣 - 因为这些将是您通过 CLI 传递的参数。这些行读作;
const args = process.argv.splice(2, process.argv.length - 2)
.map(arg => arg.replace(/^--/, ''));
创建一个 args
变量并分配一个数组,其中包含通过 CLI 传递的每个参数。使用 splice()
method. In the map()
方法从数组中省略第 2 点中的前两项,我们从每个参数中删除 --
前缀。
最后一行阅读:
execSync(`cross-env ${args.join(' ')} my-app`, {stdio:[0, 1, 2]});
调用 cross-env
并将参数作为字符串使用 Template Literals and the Array join()
method. The stdio
部分在子进程中为 stdin
、stdout
、stderr
配置管道.
注意: 如果您的目标节点的旧版本不支持 Template Literals 那么您可以将此行替换为以下内容反而。这使用 +
运算符处理字符串连接:
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"
},
这里我们要求节点调用start.js脚本。
注意 如果您希望将 start.js 文件保存在与上述根目录不同的目录位置您的项目目录,那么您需要根据需要定义 start.js 的路径。该路径应相对于 package.json。例如:
"scripts": {
"start": "node ./the/path/to/start"
},
3。 运行 npm 脚本。
npm start
脚本可以通过 运行ning:
通过 CLI 调用
$ npm start -- --env=dev --host=localhost --port=1234
调用 npm 的 start
脚本时不需要 run
部分,即 npm run start ...
。
从 Windows 或 Linux,我想要一种将 args 传递给 npm script
的方法,但要将它们作为环境变量注入
在命令行中,我将以这种方式开始我的项目:
npm run start -- --env=dev --host=localhost --port=1234
为了使用我的 cli 参数并将它们作为 env 变量注入而不考虑平台,我使用了 cross-env npm 包:
package.json
"scripts": {
"start": "cross-env env=%env% host=%host% port=%port% my-app"
},
我知道上面的语法无效,但是 start
脚本能以某种方式使用我传递的参数而不是将它们转发给 my-app
吗?
不幸的是,npm 没有,也不打算提供允许将参数传递到 npm 脚本中间的内置功能(如所述here) .参数只能传递到脚本的末尾。
对于 Linux 和 macOS,您可以使用 bash functions in npm-scripts to pass arguments to the middle of a script, as per my answer
由于需要跨平台兼容性,请考虑将当前在 start
脚本中的逻辑移动到单独的 nodejs 实用程序脚本中。然后可以通过名为 start
.
下面介绍如何以跨平台兼容的方式实现你的需求
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]});
解释:
在第一行我们
require
个节点内置execSync()
。我们将利用它 运行cross-env
并设置环境变量。Nodes builtin
process.argv
获取通过命令行传递的参数。节点process.argv
中的前两项是:- 可执行文件 运行 到 JavaScript 文件的路径。
- 正在执行的JavaScript文件的路径。
但是,我们只对数组中第三项以后的元素感兴趣 - 因为这些将是您通过 CLI 传递的参数。这些行读作;
const args = process.argv.splice(2, process.argv.length - 2) .map(arg => arg.replace(/^--/, ''));
创建一个
args
变量并分配一个数组,其中包含通过 CLI 传递的每个参数。使用splice()
method. In themap()
方法从数组中省略第 2 点中的前两项,我们从每个参数中删除--
前缀。最后一行阅读:
execSync(`cross-env ${args.join(' ')} my-app`, {stdio:[0, 1, 2]});
调用
cross-env
并将参数作为字符串使用 Template Literals and the Arrayjoin()
method. Thestdio
部分在子进程中为stdin
、stdout
、stderr
配置管道.
注意: 如果您的目标节点的旧版本不支持 Template Literals 那么您可以将此行替换为以下内容反而。这使用 +
运算符处理字符串连接:
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"
},
这里我们要求节点调用start.js脚本。
注意 如果您希望将 start.js 文件保存在与上述根目录不同的目录位置您的项目目录,那么您需要根据需要定义 start.js 的路径。该路径应相对于 package.json。例如:
"scripts": {
"start": "node ./the/path/to/start"
},
3。 运行 npm 脚本。
npm start
脚本可以通过 运行ning:
$ npm start -- --env=dev --host=localhost --port=1234
调用 npm 的 start
脚本时不需要 run
部分,即 npm run start ...
。