【问题标题】:Cross-platform way to pass environment variables as arguments to npm scripts将环境变量作为参数传递给 npm 脚本的跨平台方式
【发布时间】:2019-03-10 10:41:46
【问题描述】:

在 Windows 或 Linux 中,我想要一种将 args 传递给 npm script 的方法,但将它们作为环境变量注入

从命令行,我会以这种方式开始我的项目:

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

为了使用我的 cli 参数并将它们作为环境变量注入而不考虑平台,我使用了 cross-env npm 包:

package.json

  "scripts": {
    "start": "cross-env env=%env% host=%host% port=%port% my-app"
  },

我了解上述语法无效,但 start 脚本能否以某种方式消耗我传递的 args 而不是将它们转发给 my-app

【问题讨论】:

    标签: npm cross-platform npm-scripts


    【解决方案1】:

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

    对于 Linux 和 macOS,您可以根据我的回答 here 在 npm-scripts 中使用 bash functions 将参数传递到脚本中间。然而,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]});
    

    说明:

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

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

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

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

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

    4. 最后一行阅读:

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

      调用cross-env 并使用Template Literals 和数组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 脚本。

    可以通过 CLI 调用 npm start 脚本,方法是运行:

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

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

    【讨论】:

      猜你喜欢
      • 2020-09-09
      • 2016-01-24
      • 1970-01-01
      • 2010-11-30
      • 2020-12-04
      • 2021-01-21
      • 1970-01-01
      • 1970-01-01
      • 2021-01-03
      相关资源
      最近更新 更多