简体   繁体   English

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

[英]How to set environment variables from within package.json?

How to set some environment variables from within package.json to be used with npm start like commands?如何从package.json中设置一些环境变量以与npm start类似命令一起使用?

Here's what I currently have in my package.json :这是我目前在package.json中的内容:

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

I want to set environment variables (like NODE_ENV ) in the start script while still being able to start the app with just one command, npm start .我想在启动脚本中设置环境变量(如NODE_ENV ),同时仍然能够仅使用一个命令npm start应用程序。

Set the environment variable in the script command:在脚本命令中设置环境变量:

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

Then use process.env.NODE_ENV in your app.然后在您的应用程序中使用process.env.NODE_ENV

Note: This is for Mac & Linux only .注意:这仅适用于Mac 和 Linux For Windows refer to the comments.对于 Windows,请参阅注释。

Just use NPM package cross-env .只需使用 NPM 包cross-env Super easy.超级容易。 Works on Windows, Linux, and all environments.适用于 Windows、Linux 和所有环境。 Notice that you don't use && to move to the next task.请注意,您不使用 && 来移动到下一个任务。 You just set the env and then start the next task.您只需设置环境,然后开始下一个任务。 Credit to @mikekidder for the suggestion in one of the comments here.感谢@mikekidder在此处的评论之一中提出的建议。

From documentation:从文档:

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

Notice that if you want to set multiple global vars, you just state them in succession, followed by your command to be executed.请注意,如果要设置多个全局变量,只需依次声明它们,然后执行要执行的命令。

Ultimately, the command that is executed (using spawn) is:最终,执行的命令(使用 spawn)是:

webpack --config build/webpack.config.js

The NODE_ENV environment variable will be set by cross-env NODE_ENV环境变量将由 cross-env 设置

I just wanted to add my two cents here for future Node-explorers.我只是想在这里为未来的 Node-explorers 添加我的两分钱。 On my Ubuntu 14.04 the NODE_ENV=test didn't work, I had to use export NODE_ENV=test after which NODE_ENV=test started working too, weird.在我的 Ubuntu 14.04 上NODE_ENV=test不起作用,我不得不使用export NODE_ENV=test之后NODE_ENV=test也开始工作,很奇怪。

On Windows as have been said you have to use set NODE_ENV=test but for a cross-platform solution the cross-env library didn't seem to do the trick and do you really need a library to do this:在 Windows 上,如前所述,您必须使用set NODE_ENV=test但对于跨平台解决方案,跨环境库似乎并没有解决问题,您是否真的需要一个库来执行此操作:

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

The vertical bars are needed as otherwise Windows would crash on the unrecognized export NODE_ENV command.需要竖线,否则 Windows 会在无法识别的export NODE_ENV命令上崩溃。 I don't know about the trailing space, but just to be sure I removed them too.我不知道尾随空格,但只是为了确保我也删除了它们。

Because I often find myself working with multiple environment variables, I find it useful to keep them in a separate .env file (make sure to ignore this from your source control).因为我经常发现自己使用多个环境变量,所以我发现将它们保存在单独的.env文件中很有用(确保从源代码管理中忽略它)。 Then (in Linux) prepend export $(cat .env | xargs) && in your script command before starting your app.然后(在 Linux 中)在启动应用程序之前在脚本命令中export $(cat .env | xargs) &&

Example .env file: .env文件示例:

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

Example index.js :示例index.js

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

Example package.json :示例package.json

{
  ...
  "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",

  }
  ...
}

Unfortunately I can't seem to set the environment variables by calling a script from a script -- like "start-windows": "npm run env-windows && npm start" -- so there is some redundancy in the scripts.不幸的是,我似乎无法通过从脚本调用脚本来设置环境变量——比如"start-windows": "npm run env-windows && npm start" ——所以脚本中有一些冗余。

For a test you can see the env variables by running npm run env-linux or npm run env-windows , and test that they make it into your app by running npm run start-linux or npm run start-windows .对于测试,您可以通过运行npm run env-linuxnpm run env-windows查看环境变量,并通过运行npm run start-linuxnpm run start-windows测试它们是否进入您的应用程序。

Try this on Windows by replacing YOURENV :通过替换YOURENV在 Windows 上试试这个:

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

@luke's answer was almost the one I needed! @luke 的答案几乎是我需要的答案! Thanks.谢谢。

As the selected answer is very straightforward (and correct), but old, I would like to offer an alternative for importing variables from a .env separate file when running your scripts and fixing some limitations to Luke's answer.由于选择的答案非常简单(且正确),但很旧,我想提供一种替代方法,用于在运行脚本时从 .env 单独文件中导入变量并修复卢克答案的一些限制。 Try this:尝试这个:

::: .env file ::: ::: .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"

Then, in your package json, you will create a script that will set the variables and run it before the scripts you need them:然后,在您的 json 包中,您将创建一个脚本,该脚本将设置变量并在您需要它们的脚本之前运行它:

::: package.json ::: ::: 包.json :::

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

Some observations:一些观察:

  • The regular expression in the grep'ed cat command will clear the comments and empty lines. grep'ed cat 命令中的正则表达式将清除注释和空行。

  • The && don't need to be "glued" to npm run set-env , as it would be required if you were setting the variables in the same command. &&不需要“粘合”npm run set-env ,因为如果您在同一命令中设置变量,则需要这样做。

  • If you are using yarn, you may see a warning, you can either change it to yarn set-env or use npm run set-env --scripts-prepend-node-path && instead.如果您使用的是 yarn,您可能会看到警告,您可以将其更改为yarn set-env或使用npm run set-env --scripts-prepend-node-path &&代替。

Different environments不同的环境

Another advantage when using it is that you can have different environment variables.使用它的另一个优点是您可以拥有不同的环境变量。

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

Please, remember not to add .env files to your git repository when you have keys, passwords or sensitive/personal data in them!请记住,当您有密钥、密码或敏感/个人数据时,不要将 .env 文件添加到您的 git 存储库中!

UPDATE: This solution may break in npm v7 due to npm RFC 21更新:由于npm RFC 21 ,此解决方案可能会在 npm v7 中中断

CAVEAT: no idea if this works with yarn警告:不知道这是否适用于yarn


npm (and yarn) passes a lot of data from package.json into scripts as environment variables. npm(和 yarn)将大量数据从 package.json 传递到脚本中作为环境变量。 Use npm run env to see them all.使用npm run env来查看它们。 This is documented in https://docs.npmjs.com/misc/scripts#environment and is not only for "lifecycle" scripts like prepublish but also any script executed by npm run .这记录在https://docs.npmjs.com/misc/scripts#environment中,不仅适用于prepublish等“生命周期”脚本,还适用于npm run执行的任何脚本。

You can access these inside code (eg process.env.npm_package_config_port in JS) but they're already available to the shell running the scripts so you can also access them as $npm_... expansions in the "scripts" (unix syntax, might not work on windows?).您可以访问这些内部代码(例如$npm_...中的process.env.npm_package_config_port ),但它们已经可供运行脚本的 shell 使用,因此您也可以在“脚本”(unix 语法,可能不适用于Windows?)。

The "config" section seems intended for this use: “配置”部分似乎用于此用途:

  "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/"
  } 

An important quality of these "config" fields is that users can override them without modifying package.json !这些“配置”字段的一个重要特性是用户可以在不修改 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

See npm config and yarn config docs.请参阅npm configyarn config文档。
It appears that yarn reads ~/.npmrc so npm config set affects both, but yarn config set writes to ~/.yarnrc , so only yarn will see it :-(似乎 yarn 读取~/.npmrc所以npm config set影响两者,但是yarn config set写入~/.yarnrc ,所以只有 yarn 会看到它:-(

This will work in Windows console :这将在Windows 控制台中工作:

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

npm run aaa

output: test输出: test

See this answer for details.有关详细信息,请参阅此答案

For a larger set of environment variables or when you want to reuse them you can use env-cmd .对于更大的环境变量集,或者当您想要重用它们时,您可以使用env-cmd

./.env file: ./.env文件:

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

./package.json : ./package.json

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

suddenly i found that actionhero is using following code, that solved my problem by just passing --NODE_ENV=production in start script command option.突然我发现 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;
}

i would really appreciate to accept answer of someone else who know more better way to set environment variables in package.json or init script or something like, where app bootstrapped by someone else.我真的很感激接受其他人的回答,他们知道在 package.json 或 init 脚本或类似的东西中设置环境变量的更好方法,其中应用程序由其他人引导。

use git bash in windows.在 Windows 中使用 git bash。 Git Bash processes commands differently than cmd. Git Bash 处理命令的方式与 cmd 不同。

Most Windows command prompts will choke when you set environment variables with NODE_ENV=production like that.当您使用 NODE_ENV=production 设置环境变量时,大多数 Windows 命令提示符都会阻塞。 (The exception is Bash on Windows, which uses native Bash.) Similarly, there's a difference in how windows and POSIX commands utilize environment variables. (Windows 上的 Bash 例外,它使用本机 Bash。)同样,Windows 和 POSIX 命令如何利用环境变量也有所不同。 With POSIX, you use: $ENV_VAR and on windows you use %ENV_VAR%.在 POSIX 中,您使用:$ENV_VAR,在 Windows 上使用 %ENV_VAR%。 - cross-env doc - 跨环境文档

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

use dotenv package to declare the env variables使用 dotenv 包声明环境变量

For single environment variable对于单个环境变量

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

For multiple environment variables对于多个环境变量

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

When the NODE_ENV environment variable is set to 'production' all devDependencies in your package.json file will be completely ignored when running npm install.NODE_ENV环境变量设置为“生产”时,运行 npm install 时package.json文件中的所有 devDependencies 将被完全忽略。 You can also enforce this with a --production flag:您还可以使用--production标志强制执行此操作:

npm install --production

For setting NODE_ENV you can use any of these methods要设置NODE_ENV ,您可以使用这些方法中的任何一种

method 1 : set NODE_ENV for all node apps方法一:为所有节点应用设置NODE_ENV

Windows : Windows

set NODE_ENV=production

Linux, macOS or other unix based system : Linux, macOS or other unix的系统:

export NODE_ENV=production

This sets NODE_ENV for current bash session thus any apps started after this statement will have NODE_ENV set to production.这将为当前 bash 会话设置 NODE_ENV,因此在此语句之后启动的任何应用程序都将 NODE_ENV 设置为生产。

method 2 : set NODE_ENV for current app方法 2 :为当前应用设置NODE_ENV

NODE_ENV=production node app.js

This will set NODE_ENV for the current app only.这将仅为当前应用程序设置NODE_ENV This helps when we want to test our apps on different environments.当我们想在不同的环境中测试我们的应用程序时,这会有所帮助。

method 3 : create .env file and use it方法 3 :创建.env文件并使用它

This uses the idea explained here.这使用了这里解释的想法。 Refer this post for more detailed explanation.有关更详细的说明,请参阅此帖子。

Basically, you create a .env file and run some bash scripts to set them on the environment.基本上,您创建一个 .env 文件并运行一些 bash 脚本以在环境中设置它们。

To avoid writing a bash script, the env-cmd package can be used to load the environment variables defined in the .env file.为了避免编写 bash 脚本,可以使用 env-cmd 包来加载 .env 文件中定义的环境变量。

env-cmd .env node app.js

method 4 : Use cross-env package方法四:使用cross-env package

This package allows environment variables to be set in one way for every platform.这个包允许为每个平台以一种方式设置环境变量。

After installing it with npm, you can just add it to your deployment script in package.json as follows:使用 npm 安装后,您可以将其添加到 package.json 中的部署脚本中,如下所示:

"build:deploy": "cross-env NODE_ENV=production webpack"
{
  ...
  "scripts": {
    "start": "ENV NODE_ENV=production someapp --options"
  }
  ...
}

Most elegant and portable solution: package.json :最优雅和便携的解决方案: package.json

"scripts": {
    "serve": "export NODE_PRESERVE_SYMLINKS_MAIN=1 && vue-cli-service serve"
    },

Under windows create export.cmd and put it somewhere to your %PATH% :windows下创建export.cmd并将其放在您的%PATH%的某个位置:

@echo off

set %*

Although not directly answering the question I´d like to share an idea on top of the other answers.虽然没有直接回答这个问题,但我想在其他答案之上分享一个想法。 From what I got each of these would offer some level of complexity to achieve cross platform independency.从我得到的每一个都会提供一定程度的复杂性来实现跨平台的独立性。

On my scenario all I wanted, originally, to set a variable to control whether or not to secure the server with JWT authentication (for development purposes)在我的场景中,我最初想要设置一个变量来控制是否使用 JWT 身份验证来保护服务器(出于开发目的)

After reading the answers I decided simply to create 2 different files, with authentication turned on and off respectively.阅读答案后,我决定简单地创建 2 个不同的文件,分别打开和关闭身份验证。

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

The files are simply wrappers that call the original index.js file (which I renamed to appbootstrapper.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
    }
}

Perhaps this can help someone else也许这可以帮助别人

If you:如果你:

  • Are currently using Windows;当前正在使用 Windows;
  • Have git bash installed;安装了 git bash;
  • Don't want to use set ENV in your package.json which makes it only runnable for Windows dev machines;不想在你的 package.json 中使用set ENV ,这使它只能在 Windows 开发机器上运行;

Then you can set the script shell of node from cmd to git bash and write linux-style env setting statements in package.json for it to work on both Windows/Linux/Mac.然后,您可以将 node 的脚本 shell 从 cmd 设置为 git bash,并在package.json中编写 linux 风格的环境设置语句,使其在 Windows/Linux/Mac 上都可以工作。

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

You should not set ENV variables in package.json .您不应该在package.json中设置 ENV 变量。 actionhero uses NODE_ENV to allow you to change configuration options which are loaded from the files in ./config . actionhero 使用NODE_ENV允许您更改从./config中的文件加载的配置选项。 Check out the redis config file , and see how NODE_ENV is uses to change database options in NODE_ENV=test查看redis 配置文件,了解如何使用 NODE_ENV 更改NODE_ENV=test中的数据库选项

If you want to use other ENV variables to set things (perhaps the HTTP port), you still don't need to change anything in package.json .如果您想使用其他 ENV 变量来设置东西(可能是 HTTP 端口),您仍然不需要更改package.json中的任何内容。 For example, if you set PORT=1234 in ENV and want to use that as the HTTP port in NODE_ENV=production , just reference that in the relevant config file, IE:例如,如果您在 ENV 中设置PORT=1234并希望将其用作NODE_ENV=production中的 HTTP 端口,只需在相关配置文件 IE 中引用它:

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

Note : In order to set multiple environment variable, script should goes like this注意:为了设置多个环境变量,脚本应该是这样的

  "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",
  },

Environment variables are noting to do with your node application!环境变量与您的节点应用程序无关! The only role of the process.env is to provide the system environment variables to your application. process.env 的唯一作用是为您的应用程序提供系统环境变量。 In case you need to add environment variables, you should add it in your docker/vm/vagrant configuration file not in the start script of your application.如果您需要添加环境变量,则应将其添加到 docker/vm/vagrant 配置文件中,而不是应用程序的启动脚本中。

If you are going to pass an argument to node instance, the best and only way is to use node process.argv instead of rocess.env.如果您打算将参数传递给节点实例,最好也是唯一的方法是使用节点 process.argv 而不是 rocess.env。

The only case you need to use process.env is that your cloud provider enforces some configurations with which your app must comply, even in that case, they set the environment variables not you.您需要使用 process.env 的唯一情况是您的云提供商强制执行您的应用程序必须遵守的一些配置,即使在这种情况下,他们设置的是环境变量而不是您。

Here is how to pass arguments to your app.这是将参数传递给您的应用程序的方法。 You've probably known already.你可能已经知道了。

node app.js  port=5000 profile=admin

Then,然后,

/**
 * Get the passed node argument by key.
 * @param key of node argument
 * @returns {string}
 */
export function getArg(key: string): string {
    return process.argv
        .map(e => e.split('=')) // [ [a b] , [c d]]
        .filter(e => e.length == 2) //[[a b], [c d]]
        .map(e => ({ [e[0]]: e[1] })) // [{a:b}, {c:d}]
        .reduce((p, c) => ({ ...p, ...c }))[key]
}

Example Scenario:示例场景:

  • App has multiple profiles "admin" , "public", and "subscriber".应用程序有多个配置文件“admin”、“public”和“subscriber”。
  • App runs only upon user request, (for example, admin wants to run the app, then you run the app on admin profile)应用程序仅在用户请求时运行,(例如,管理员想要运行该应用程序,然后您在管理员配置文件上运行该应用程序)

package.json包.json

{
"start:admin":"node  app.js profile=admin port=5000", 
"start:public":"node app.js profile=public port=5001", 
"start:subscriber":"node app.js profile=subscriber port=5002", 
}

Just tried to explain the nuance between process.env and process.argv.只是试图解释 process.env 和 process.argv 之间的细微差别。

Take it Easy!别紧张!

In addition to use of cross-env as documented above, for setting a few environment variables within a package.json 'run script', if your script involves running NodeJS, then you can set Node to pre-require dotenv/config :除了使用上面记录的cross-env之外,如果您的脚本涉及运行package.json ,那么您可以将 Node 设置为 pre-require 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)'",
  }
}

This will cause your node interpreter to require dotenv/config , which will itself read the .env file in the present working directory from which node was called.这将导致您的节点解释器需要dotenv/config ,它本身将读取当前工作目录中调用节点的.env文件。

The .env format is lax or liberal: .env格式松散或自由:

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

#Blank lines are no problem

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM