如何从package.json中设置环境变量?

如何设置一些环境变量从package.json使用与npm start一样的命令?

这是我目前在我的package.json:

{
...
"scripts": {
"help": "tagove help",
"start": "tagove start"
}
...
}

我想在启动脚本中设置环境变量(如NODE_ENV),同时仍然能够用一个命令npm start启动应用程序。

802930 次浏览

突然我发现actionhero正在使用以下代码,这解决了我的问题,只是通过在启动脚本命令选项--NODE_ENV=production

if(argv['NODE_ENV'] != null){
api.env = argv['NODE_ENV'];
} else if(process.env.NODE_ENV != null){
api.env = process.env.NODE_ENV;
}

我真的很感激接受其他人的答案谁知道更多更好的方法设置包中的环境变量。Json或init脚本,这些都是由别人引导的。

你不应该在package.json中设置ENV变量。actionhero使用NODE_ENV来允许你改变从./config文件中加载的配置选项。查看Redis配置文件,并查看如何使用NODE_ENV更改NODE_ENV=test中的数据库选项

如果您想使用其他ENV变量来设置内容(可能是HTTP端口),您仍然不需要更改package.json中的任何内容。例如,如果你在ENV中设置了PORT=1234,并且想要使用它作为NODE_ENV=production中的HTTP端口,只需在相关的配置文件中引用它,IE:

# in config/servers/web.js
exports.production = {
servers: {
web: function(api){
return {
port: process.env.PORT
}
}
}
}

在script命令中设置环境变量:

...
"scripts": {
"start": "node app.js",
"test": "NODE_ENV=test mocha --reporter spec"
},
...

然后在应用程序中使用process.env.NODE_ENV

注意:这是针对Mac和Linux只的。对于Windows,请参阅注释。

我只是想在这里为未来的node探索者补充我的意见。在我的Ubuntu 14.04上,NODE_ENV=test不能工作,我不得不使用export NODE_ENV=test,然后NODE_ENV=test也开始工作了,真奇怪。

在Windows上,如前所述,你必须使用set NODE_ENV=test,但对于跨平台的解决方案,cross-env库似乎没有做到这一点,你真的需要一个库来做到这一点吗:

export NODE_ENV=test || set NODE_ENV=test&& yadda yadda

垂直条是需要的,否则Windows会在无法识别的export NODE_ENV命令下崩溃。我不知道后面的空格,但为了确保我把它们也去掉了。

只需使用NPM包cross-env。超级简单。适用于Windows、Linux和所有环境。注意你不用&&进行下一个任务。您只需设置env,然后开始下一个任务。感谢@mikekidder其中一个评论是中的建议。

从文档:

{
"scripts": {
"build": "cross-env NODE_ENV=production OTHERFLAG=myValue webpack --config build/webpack.config.js"
}
}

注意,如果您想设置多个全局变量,您只需连续地声明它们,然后再加上要执行的命令。

最终,执行的命令(使用spawn)是:

webpack --config build/webpack.config.js

NODE_ENV环境变量将由cross-env设置

虽然没有直接回答这个问题,但我想在其他答案的基础上分享一个想法。从我得到的信息来看,每一个都提供了一定程度的复杂性来实现跨平台独立性。

在我的场景中,最初我只想设置一个变量来控制是否使用JWT身份验证来保护服务器(出于开发目的)

在阅读了答案后,我决定简单地创建2个不同的文件,分别打开和关闭身份验证。

  "scripts": {
"dev": "nodemon --debug  index_auth.js",
"devna": "nodemon --debug  index_no_auth.js",
}

这些文件只是调用原始index.js文件的包装器(我将其重命名为appbootstrapper.js):

//index_no_auth.js authentication turned off
const bootstrapper = require('./appbootstrapper');
bootstrapper(false);


//index_auth.js authentication turned on
const bootstrapper = require('./appbootstrapper');
bootstrapper(true);


class AppBootStrapper {


init(useauth) {
//real initialization
}
}

也许这能帮助到其他人

{
...
"scripts": {
"start": "ENV NODE_ENV=production someapp --options"
}
...
}

在Windows上尝试替换YOURENV:

  {
...
"scripts": {
"help": "set NODE_ENV=YOURENV && tagove help",
"start": "set NODE_ENV=YOURENV && tagove start"
}
...
}

因为我经常需要处理多个环境变量,所以我发现将它们保存在单独的.env文件中很有用(请确保在源代码控制中忽略这一点)。然后(在Linux中)在启动应用程序之前在脚本命令中前置export $(cat .env | xargs) &&

示例.env文件:

VAR_A=Hello World
VAR_B=format the .env file like this with new vars separated by a line break

例# EYZ0:

console.log('Test', process.env.VAR_A, process.env.VAR_B);

例# EYZ0:

{
...
"scripts": {
"start": "node index.js",


"env-linux": "export $(cat .env | xargs) && env",
"start-linux": "export $(cat .env | xargs) && npm start",


"env-windows": "(for /F \"tokens=*\" %i in (.env) do set %i)",
"start-windows": "(for /F \"tokens=*\" %i in (.env) do set %i) && npm start",


}
...
}

不幸的是,我似乎不能通过从脚本(如"start-windows": "npm run env-windows && npm start")调用脚本来设置环境变量,因此脚本中存在一些冗余。

对于一个测试,你可以通过运行npm run env-linuxnpm run env-windows来查看env变量,并通过运行npm run start-linuxnpm run start-windows来测试它们是否进入你的应用程序。

这将在Windows控制台工作:

"scripts": {
"setAndStart": "set TMP=test&& node index.js",
"otherScriptCmd": "echo %TMP%"
}

# EYZ0

< p >输出: # EYZ0 < / p >

详见这个答案

对于更大的环境变量集,或者当您想重用它们时,可以使用env-cmd

另外,.env文件也可以与direnv文件一起工作。

# EYZ0文件:

# This is a comment
ENV1=THANKS
ENV2=FOR ALL
ENV3=THE FISH

# EYZ0:

{
"scripts": {
"test": "env-cmd mocha -R spec"
}
}

更新:由于npm RFC 21,这个解决方案可能会在npm v7中崩溃

警告:不知道这是否适用于yarn


npm(和yarn)从包中传递很多的数据。Json作为环境变量放入脚本中。使用npm run env查看它们。这是在https://docs.npmjs.com/misc/scripts#environment中记录的,不仅是“生命周期”;像prepublish这样的脚本,以及由npm run执行的任何脚本。

你可以访问这些内部代码(例如JS中的process.env.npm_package_config_port),但它们已经对运行脚本的shell可用,所以你也可以访问它们作为$npm_...扩展在"scripts"(unix语法,可能不能在windows上工作?)

“config"部分似乎是为了这个用途:

  "name": "myproject",
...
"config": {
"port": "8010"
},
"scripts": {
"start": "node server.js $npm_package_config_port",
"test": "wait-on http://localhost:$npm_package_config_port/ && node test.js http://localhost:$npm_package_config_port/"
}

这些“config"字段是用户可以在不修改package.json的情况下重写它们!

$ npm run start


> myproject@0.0.0 start /home/cben/mydir
> node server.js $npm_package_config_port


Serving on localhost:8010


$ npm config set myproject:port 8020
$ git diff package.json  # no change!
$ cat ~/.npmrc
myproject:port=8020


$ npm run start


> myproject@0.0.0 start /home/cben/mydir
> node server.js $npm_package_config_port


Serving on localhost:8020

参见npm配置纱配置文档。
yarn读取~/.npmrc,因此npm config set影响两者,但yarn config set写入~/.yarnrc,因此只有yarn可以看到:-(

@luke的回答几乎就是我需要的!谢谢。

由于所选的答案非常直接(正确),但旧,我想提供一个替代方案,用于在运行脚本时从.env单独文件导入变量,并修复Luke的答案的一些限制。 试试这个:< / p >

::: .env文件:::

# This way, you CAN use comments in your .env files
NODE_PATH="src/"


# You can also have extra/empty lines in it
SASS_PATH="node_modules:src/styles"


然后,在你的package json中,你将创建一个设置变量的脚本,并在你需要它们的脚本之前运行它:

:::包。json:::

scripts: {
"set-env": "export $(cat .env | grep \"^[^#;]\" |xargs)",
"storybook": "npm run set-env && start-storybook -s public"
}

一些观察:

  • grep'ed cat命令中的正则表达式将清除注释和空行。

  • &&不需要从“glued"npm run set-env,因为如果你在同一个命令中设置变量,这将是必需的。

  • 如果你正在使用yarn,你可能会看到一个警告,你可以将它改为yarn set-env或使用npm run set-env --scripts-prepend-node-path &&代替。

不同的环境

使用它的另一个优点是可以使用不同的环境变量。

scripts: {
"set-env:production": "export $(cat .production.env | grep \"^[^#;]\" |xargs)",
"set-env:development": "export $(cat .env | grep \"^[^#;]\" |xargs)",
}

请记住,当你有密钥、密码或敏感/个人数据时,不要将.env文件添加到git存储库中!

在windows中使用git bash。Git Bash处理命令的方式与cmd不同。

当您像这样使用NODE_ENV=production设置环境变量时,大多数Windows命令提示符都会阻塞。(Windows上的Bash是个例外,它使用原生Bash。)类似地,窗口和POSIX命令利用环境变量的方式也有所不同。对于POSIX,您使用:$ENV_VAR,在windows上使用%ENV_VAR%。 -交叉环境文件

{
...
"scripts": {
"help": "tagove help",
"start": "env NODE_ENV=production tagove start"
}
...
}

使用dotenv包来声明env变量

为了设置多个环境变量,脚本应该如下所示

  "scripts": {
"start": "set NODE_ENV=production&& set MONGO_USER=your_DB_USER_NAME&& set MONGO_PASSWORD=DB_PASSWORD&& set MONGO_DEFAULT_DATABASE=DB_NAME&& node app.js",
},

对于单个环境变量

 "scripts": {
"start": "set NODE_ENV=production&& node server.js"
}

对于多个环境变量

 "scripts": {
"start": "set NODE_ENV=production&& set PORT=8000&& node server.js"
}
最优雅和便携的解决方案: # EYZ0: < / p >
"scripts": {
"serve": "export NODE_PRESERVE_SYMLINKS_MAIN=1 && vue-cli-service serve"
},

windows下创建export.cmd,并把它放在%PATH%的某个地方:

@echo off


set %*

NODE_ENV环境变量被设置为'production'时,当运行npm install时,package.json文件中的所有devDependencies将被完全忽略。你也可以使用--production标志来强制执行:

npm install --production

要设置NODE_ENV,您可以使用这些方法中的任何一个

方法1:为所有节点应用设置NODE_ENV

# EYZ0:

set NODE_ENV=production

基于Linux, macOS or other unix的系统:

export NODE_ENV=production

这将为当前bash会话设置NODE_ENV,因此在此语句后启动的任何应用程序都将NODE_ENV设置为生产。

方法2:设置当前应用的NODE_ENV

NODE_ENV=production node app.js

这将仅为当前应用设置NODE_ENV。当我们想要在不同的环境中测试应用程序时,这很有帮助。

方法3:创建.env文件并使用它

这使用了这里解释的想法。请参考这篇文章了解更详细的解释。

基本上,您创建一个.env文件,并运行一些bash脚本在环境上设置它们。

为了避免编写bash脚本,可以使用env-cmd包来加载.env文件中定义的环境变量。

env-cmd .env node app.js

方法4:使用cross-env package

这个包允许以一种方式为每个平台设置环境变量。

在用npm安装它之后,你可以把它添加到你的部署脚本中。Json格式如下:

"build:deploy": "cross-env NODE_ENV=production webpack"

如果你:

  • 目前正在使用Windows;
  • 安装git bash;
  • 不想在包中使用set ENV。json,这使得它只能在Windows开发机器上运行;

然后你可以将node的脚本shell从cmd设置为git bash,并在package.json中编写Linux风格的env设置语句,使其在Windows/Linux/Mac上都可以工作。

$ npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe"

除了使用上面记录的cross-env,在package.json“运行脚本”中设置一些环境变量,如果你的脚本涉及运行NodeJS,那么你可以将Node设置为预先要求dotenv/config:

{
scripts: {
"eg:js": "node -r dotenv/config your-script.js",
"eg:ts": "ts-node -r dotenv/config your-script.ts",
"test":  "ts-node -r dotenv/config -C 'console.log(process.env.PATH)'",
}
}

这将导致您的节点解释器需要dotenv/config,它自己将读取当前工作目录中的.env文件,从该目录中调用节点。

.env格式是宽松的或自由的:

# Comments are permitted
FOO=123
BAR=${FOO}
BAZ=Basingstoke Round About


#Blank lines are no problem

从包中运行node.js脚本。带有多个环境变量的Json:

  1. 包中。json文件:

    "scripts": {
"do-nothing": "set NODE_ENV=prod4 && set LOCAL_RUN=true && node ./x.js",
},

X.js文件可以是:

let env     = process.env.NODE_ENV;
let isLocal = process.env.LOCAL_RUN;


console.log("ENV"    , env);
console.log("isLocal", isLocal);