将环境变量作为参数传递给npm脚本的跨平台方式 [英] Cross-platform way to pass environment variables as arguments to npm scripts

查看:167
本文介绍了将环境变量作为参数传递给npm脚本的跨平台方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从Windows或Linux上,我都希望有一种方法将args传递给 npm脚本,但要将它们作为环境变量注入

From both Windows or Linux, I want a way to pass args to a npm script, but have them be injected as environment variables

在命令行中,我将以这种方式启动项目:

From the command line, I'd start my project in this fashion:

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

要消耗我的客户端&无论平台如何,都将它们作为env变量注入,我使用了 cross-env npm package:

To consume my cli args & inject them as env variables regardless of platform, I used the cross-env npm package :

package.json

package.json

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

我知道上面的语法无效,但是 start 脚本可以以某种方式消耗我传递的args而不是转发他们继续使用 my-app

I understand the above is invalid syntax, but can that start script somehow consume the args I pass instead of forwarding them on to my-app?

推荐答案

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

Unfortunately npm does not, nor intends to, provide a builtin feature which allows arguments to be passed to the middle of a npm script (as stated here). Arguments can only be passed to the end of a script.

对于Linux和macOS,您可以使用 bash函数在npm-scripts中将参数传递到脚本中间/ questions / 51590079 / passing-arguments-to-combined-npm-script / 51595953#51595953>此处。但是Windows会选择这种解决方案。

For Linux and macOS you can utilize bash functions in npm-scripts to pass arguments to the middle of a script, as per my answer here. However Windows will choke at such a solution.

由于跨平台兼容性是必需的,因此请考虑移动当前 start 脚本转换为单独的nodejs实用程序脚本。然后可以通过名为 start 的npm脚本调用nodejs脚本。

As cross-platform compatibility is a requirement, consider moving the logic currently in your start script into a separate nodejs utility script. The nodejs script can then be invoked via the npm-script named start.

以下内容介绍了如何实现

The following describes how to achieve your requirement in a cross-platform compatible way.

按如下所示创建一个nodejs脚本。让我们将脚本命名为 start.js 并将其保存在项目目录的根目录中,即与您的 package.json 文件当前所在的目录相同。

Create a nodejs script as follows. Let's name the script start.js and save it in the root of your project directory, i.e. at the same level where your package.json file currently resides.

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. 在第一行中,我们要求内置 execSync() 。我们将利用它来运行 cross-env 并设置环境变量。

  1. In the first line we require nodes builtin execSync(). We'll utilize this to run cross-env and set the environment variables.

内置节点< a href = https://nodejs.org/docs/latest/api/process.html#process_process_argv rel = nofollow noreferrer> process.argv 获取通过命令行传递的参数。节点 process.argv 中的前两项是:

Nodes builtin process.argv obtains the arguments passed via the command-line. The first two items in nodes process.argv are:



  • 正在执行的JavaScript文件的路径。

但是,我们只对数组中第三项以后的元素感兴趣-因为这些将是您通过CLI传递的参数。这些行的内容为:

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(/^--/, ''));

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

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.

最后一行是

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

调用 cross-env 并放置参数使用模板文字和数组< a href = https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/join rel = nofollow noreferrer> join() 方法。 stdio 部分配置了在子进程中用于 stdin stdout stderr 的管道。

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.

注意:如果您定位的旧版本节点不支持 Template Literals (模板文字),那么您可以将该行替换为以下内容。这使用 + 运算符处理字符串连接:

Note: If your targeting older versions of node that don't support Template Literals then you can substitute this line with the following instead. This handles string concatenation using the + operator:

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

类似地,如果不支持ES6箭头功能,请更改 map() 使用标准功能。例如:

Similarly, if ES6 arrow functions aren't supported change the map() to use standard functions. For instance:

.map(function(arg) {
  return arg.replace(/^--/, '');
});






2。 package.json脚本。



package.json 中重新定义您的 start 脚本,如下所示:


2. package.json script.

Redefine your start script in package.json as follows:

"scripts": {
  "start": "node start"
},

在这里,我们要求节点调用 start.js 脚本。

Here we are asking node to invoke the start.js script.

注意如果您希望将 start.js 文件保存在以下目录中与前面提到的项目目录的根目录不同,则需要根据需要定义 start.js 的路径。该路径应相对于 package.json 。例如:

Note If you prefer to save the start.js file in a directory location which is different to the aforementioned root of your project directory, then you'll need to define the path to start.js as necessary. The path should be relative to package.json. For instance:

"scripts": {
  "start": "node ./the/path/to/start"
},






3。运行npm脚本。



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

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

运行部分,即 start 脚本时,不需要> npm run start ... 。

The run part, i.e. npm run start ... is not required when invoking the npm's start script.

这篇关于将环境变量作为参数传递给npm脚本的跨平台方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆