将环境变量作为参数传递给npm脚本的跨平台方式

时间:2018-10-05 00:49:04

标签: npm cross-platform 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吗?

1 个答案:

答案 0 :(得分:3)

不幸的是,npm既不也不打算提供一个内置功能,该功能允许将参数传递到npm脚本(如here)的中间。参数只能传递到脚本的末尾。

对于Linux和macOS,您可以根据我的回答bash functions在npm-scripts中使用here来将参数传递到脚本的中间。但是Windows会选择这种解决方案。

由于需要跨平台兼容性,因此请考虑将start脚本中当前的逻辑移动到单独的nodejs实用程序脚本中。然后可以通过名为start的npm-script调用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]});

说明:

  1. 在第一行中,我们require个内置于execSync()的节点。我们将利用它来运行cross-env并设置环境变量。

  2. 内置process.argv
  3. 节点获取通过命令行传递的参数。节点process.argv中的前两项是:

    • 运行JavaScript文件的可执行文件的路径。
    • 正在执行的JavaScript文件的路径。
  4. 但是,我们只对数组中第三项以后的元素感兴趣-因为这些将是您通过CLI传递的参数。这些行的内容;

    const args = process.argv.splice(2, process.argv.length - 2)
        .map(arg => arg.replace(/^--/, ''));
    

    创建一个args变量,并分配一个包含通过CLI传递的每个参数的数组。使用splice()方法从数组中省略了点2中的前两项。在map()方法中,我们从每个参数中删除了--前缀。

  5. 最后一行是

    execSync(`cross-env ${args.join(' ')} my-app`, {stdio:[0, 1, 2]});
    

    调用cross-env并使用Template Literals和Array join()方法将参数作为字符串放置。 stdio部分在子进程中为stdinstdoutstderr配置管道。

注意:如果您定位的旧版本节点不支持 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-script。

运行以下命令可以通过CLI调用npm start脚本:

$ npm start -- --env=dev --host=localhost --port=1234

调用npm的run脚本时,不需要npm run start ...部分,即start