Como definir variáveis ​​de ambiente no package.json

313

Como definir algumas variáveis ​​de ambiente de dentro package.jsonpara serem usadas com npm startcomandos semelhantes?

Aqui está o que eu tenho atualmente no meu package.json:

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

Eu quero definir variáveis ​​de ambiente (como NODE_ENV) no script de inicialização enquanto ainda consigo iniciar o aplicativo com apenas um comando npm start,.

dev.meghraj
fonte
Você pode ler esta resposta stackoverflow.com/a/57509175/11127383
Daniel Danielecki

Respostas:

434

Defina a variável de ambiente no comando de script:

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

Em seguida, use process.env.NODE_ENVno seu aplicativo.

Nota: envgarante que ele funcione entre plataformas. Você pode omitir se você se importa apenas com Mac / Linux.

cesar
fonte
65
Alguém descobriu uma alternativa para o Windows ..?
Infinito
65
O @infinity usa cross-env e é muito fácil de usar.
Mikekidder
106
@infinity use set NODE_ENV=test&& mocha --reporter spec- não há espaço entre o teste e && de propósito.
21716 Jamie Penney
18
"test": "NODE_ENV=test mocha --reporter spec"não funcionará em sistemas Windows.
Benny Neugebauer
7
O @infinity @ jamie-penney env NODE_ENV=test mocha --reporter specusará a variável de ambiente declarada de maneira nativa entre plataformas, mas a chave é que ela é usada pelo npm de maneira ad hoc e única, apenas para a execução do script npm. (Não está definido ou exportado para referência futura.) Desde que você esteja executando seu comando a partir do script npm, não há problema. Além disso, o "&&" deve ser removido ao fazê-lo dessa maneira.
estaples
219

Basta usar o pacote NPM entre env . Super fácil. Funciona em Windows, Linux e todos os ambientes. Observe que você não usa && para passar para a próxima tarefa. Você acabou de definir o ambiente e depois iniciar a próxima tarefa. Os nossos agradecimentos a @mikekidder pela sugestão em um dos comentários aqui.

Da documentação:

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

Observe que se você deseja definir vários vars globais, basta indicá-los em sucessão, seguidos pelo seu comando a ser executado.

Por fim, o comando que é executado (usando spawn) é:

webpack --config build/webpack.config.js

A NODE_ENVvariável de ambiente será definida por ambiente

TetraDev
fonte
Barras invertidas triplos pode ser usado para escapar citações necessários:"test": "cross-env TS_NODE_COMPILER_OPTIONS='{\\\"module\\\":\\\"commonjs\\\"}' mocha"
BVJ
1
Melhor solução porque plataformas cruzadas.
22419 bernardn
Alguém pode finalmente me ajudar a decidir se devo usar envou cross-env? Por um lado, o env não exige que eu instale nada e, por outro lado, cross-envé mais popular. Alguém pode confirmar se envfunciona em todas as plataformas?
Rishav 01/04
2
O @Rishav envnão funciona como está em todas as plataformas, daí a razão de cross-envexistir. Basta usar cross-enve terminar com isso.
TetraDev
38

Como geralmente trabalho com várias variáveis ​​de ambiente, acho útil mantê-las em um .envarquivo separado (ignore isso no controle de origem).

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

Em seguida, inclua export $(cat .env | xargs) &&antes do seu comando de script.

Exemplo:

{
  ...
  "scripts": {
    ...
    "start": "export $(cat .env | xargs) && echo do your thing here",
    "env": "export $(cat .env | xargs) && env",
    "env-windows": "export $(cat .env | xargs) && set"
  }
  ...
}

Para um teste, você pode visualizar as variáveis ​​env executando npm run env(linux) ou npm run env-windows(windows).

Lucas
fonte
1
Muito bom, quase fez o trabalho para mim! Gostaria de adicionar alguns comentários: - Você não pode ter linhas vazias no arquivo .env - Comentários no arquivo .env interromperão seu script - Se vários scripts usarem o mesmo arquivo .env, será necessário repetir isso - Eu tive que remover o espaço antes &&para que ele funcionasse - Se você tiver vários arquivos .env, pode ser um pouco mais difícil de manter Sua resposta me inspirou a preparar esta sugestão: stackoverflow.com/questions/25112510/…
Felipe N Moura
37

Eu só queria adicionar meus dois centavos aqui para futuros exploradores de nós. No meu Ubuntu 14.04 o NODE_ENV=testnão funcionou, eu tive que usar export NODE_ENV=testdepois do qual NODE_ENV=testcomecei a trabalhar também, estranho.

No Windows, como já foi dito, você deve usar, set NODE_ENV=testmas para uma solução de plataforma cruzada, a biblioteca entre ambientes não pareceu fazer o truque e você realmente precisa de uma biblioteca para fazer isso:

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

As barras verticais são necessárias, caso contrário, o Windows trava no export NODE_ENVcomando não reconhecido : D. Não sei quanto ao espaço de fuga, mas só para ter certeza de que também os removi.

TeemuK
fonte
6
Você usou &&? NODE_ENV=test yaddameios "run yadda, estabelecendo NODE_ENVdentro yadda. 's variáveis de ambiente NODE_ENV=test && yaddasignifica 'conjunto NODE_ENVdentro do ambiente local, mas não exportá-lo, em seguida, executar yadda'. NODE_ENV=test yaddaé a abordagem preferida.
Josh Kelley
Desculpe por não verificar minha conta stackoverflow há algum tempo. Mas basicamente o Windows bobo não funcionou usando NODE_ENV=test && npm run testalgo parecido. Fiz uma solução melhor usando process.env["NODE_ENV"] = "testing";dentro do meu arquivo testhelper.js.
TeemuK
5
@TeemuK apenas para adicionar meus dois centavos também, quando você executa seu comando com as &&suas variáveis ​​de ambiente perdidas, definir variáveis ​​de ambiente sem exportação funciona apenas no comando atual (o que não é nada). para executar o comando com a variável env sem exportar u fazer: NODE_ENV=test npm run test. Finalmente, o motivo pelo qual funcionou depois que você exportou é porque sua variável está disponível (exportada) na sessão e seu NODE_ENV sem exportação não estava fazendo nada.
Tarek
19

Tente isso no Windows, substituindo YOURENV:

  {
    ...
     "scripts": {
       "help": "set NODE_ENV=YOURENV && tagove help",
       "start": "set NODE_ENV=YOURENV && tagove start"
     }
    ...
  }
Pascal Mayr
fonte
1
Sim! Obrigado! Esta foi a resposta que eu estava procurando! : D
Daniel Tonon
6
Eu tive que remover o espaço antes do &&.
Kenneth Solberg
O comentário de @ KennethSolberg foi o toque final que fez funcionar para mim (somente Windows)
ulu 01/02
Eu também tive o problema de espaço. Ao registrar o comprimento da string, eu poderia dizer que o espaço foi adicionado. Tentei aspas escapadas - e elas foram realmente armazenadas no ambiente. Tentei outros delimitadores sem sucesso. Remover o espaço ou aparar o valor, que me parece errado, foram as únicas maneiras de contornar esse problema.
Neil Guy Lindberg
8

de repente, descobri que o actionhero está usando o seguinte código, que resolveu meu problema, apenas passando a --NODE_ENV=productionopção de comando start script.

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

Eu realmente gostaria de aceitar a resposta de outra pessoa que conhece uma maneira melhor de definir variáveis ​​de ambiente no package.json ou no script init ou algo parecido, onde o aplicativo é inicializado por outra pessoa.

dev.meghraj
fonte
4

Para um conjunto maior de variáveis ​​de ambiente ou quando você deseja reutilizá-las, pode usar env-cmd.

./.env Arquivo:

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

./package.json:

{
  "scripts": {
    "test": "env-cmd mocha -R spec"
  }
}
KARASZI István
fonte
como você usa ENV1 no script?
ValRob 15/12/19
O de sempreprocess.env.ENV1
KARASZI István
mas dentro do package.json? Eu tinha lido que é impossível (?)
ValRob
Eu não entendo Por que você faria isso?
KARASZI István
talvez seja uma abordagem boba, mas eu atualizei o macOs Catalina e agora o comando mongodb não está funcionando, portanto, preciso especificar os dados / pasta mongod --dbpath ~/data/db. Eu quero executar algo parecido npm mongodbe que irá obter a variável de ambiente dbpath e executar o mondodb como sempre ... e .. eu quero compartilhá-lo com outros membros.
ValRob
2

Embora não responda diretamente à pergunta, gostaria de compartilhar uma ideia sobre as outras respostas. Pelo que obtive, cada uma delas ofereceria algum nível de complexidade para obter independência entre plataformas.

No meu cenário, tudo que eu queria, originalmente, definir uma variável para controlar se protegia ou não o servidor com autenticação JWT (para fins de desenvolvimento)

Depois de ler as respostas, decidi simplesmente criar 2 arquivos diferentes, com a autenticação ativada e desativada, respectivamente.

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

Os arquivos são simplesmente invólucros que chamam o arquivo index.js original (ao qual renomei 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
    }
}

Talvez isso possa ajudar outra pessoa

Luiz Henrique Martins Lins Rol
fonte
2
{
  ...
  "scripts": {
    "start": "ENV NODE_ENV=production someapp --options"
  }
  ...
}
Cailean
fonte
2

Isso funcionará no console do Windows :

"scripts": {
  "aaa": "set TMP=test && npm run bbb",
  "bbb": "echo %TMP%"
}

npm run aaa

resultado: test

Veja esta resposta para detalhes.

Sergey
fonte
5
Deveria ser set TMP=test&& npm run bbb. O espaço antes &&também cound como parte do então NODE_ENVcorda
FisNaN
@FisNaN Não deve ser o caso se você o envolver entre aspas ".
kaiser
2

use git bash no windows. O Git Bash processa comandos de maneira diferente do cmd.

A maioria dos prompts de comando do Windows é bloqueada quando você define variáveis ​​de ambiente com NODE_ENV = produção como essa. (A exceção é o Bash no Windows, que usa o Bash nativo.) Da mesma forma, há uma diferença em como o Windows e os comandos POSIX utilizam variáveis ​​de ambiente. Com o POSIX, você usa: $ ENV_VAR e, no Windows,% ENV_VAR%. - documento entre env

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

use o pacote dotenv para declarar as variáveis ​​env

Shubham Shaw
fonte
1

Você não deve definir variáveis ​​ENV em package.json. O actionhero usa NODE_ENVpara permitir que você altere as opções de configuração carregadas dos arquivos ./config. Confira o arquivo de configuração redis e veja como o NODE_ENV é usado para alterar as opções do banco de dados emNODE_ENV=test

Se você quiser usar outras variáveis ​​ENV para definir as coisas (talvez a porta HTTP), ainda não precisará alterar nada package.json. Por exemplo, se você definir PORT=1234em ENV e quiser usá-la como a porta HTTP NODE_ENV=production, apenas faça referência a isso no arquivo de configuração relevante, IE:

# in config/servers/web.js
exports.production = { 
  servers: {
    web: function(api){
      return {
       port: process.env.PORT
      }
    }
  }
}
Evan
fonte
ótimo. Eu acho que você não leu minha pergunta .. meu problema é como definir NODE_ENV e não o que é útil.
precisa saber é o seguinte
1
Se você deseja definir várias propriedades do ambiente, não o faça no npm startcomando Usando o trecho acima, se você queria correr o servidor usando a porta ENV seria: export PORT=1234; npm start. Você pode anexar quantas declarações ENV forem necessárias, mas elas não pertencem ao arquivo package.json. Se você está preocupado com certificando-se de que eles existem, você deve usar padrões em seu arquivo de configuração: port: process.env.PORT || 8080.
Tony
1
Talvez uma maneira alternativa de explicar isso seja que NODE_ENV (e outras variáveis ​​de ambiente) fazem parte do ambiente (daí o nome). Geralmente, são propriedades do servidor em que você está executando o aplicativo e não o seu aplicativo. Você pode configurá-los manualmente através do comando que exec, ou seja: NODE_ENV=test npm startou tê-los definido pelo shell
Evan
3
Discordo. o uso de ./config para cada ambiente limita o uso de ambientes estáticos quando você implanta seu aplicativo. Essa é uma filosofia desatualizada que não permitirá que você crie novos tipos de ambientes quando necessário. IE para cada novo ambiente que você desejar, você precisará adicionar um .config. Definir variáveis ​​de ambiente em tempo de execução pode ser uma opção superior quando sua pilha de tecnologia exigir mais flexibilidade. Eu acho que seu ./config seria bom para configurar "tipos" de ambientes, mas seu aplicativo seria mais flexível se você pudesse definir coisas como strings dsn e pontos de extremidade da API em tempo de execução.
precisa
@JesseGreathouse - Eu tenho um aplicativo node.js e preciso definir as variáveis ​​de ambiente em tempo de execução - em qual arquivo eu as configuraria?
Roger Dodger
1

O npm (e yarn) passa muitos dados do package.json para scripts como variáveis ​​de ambiente. Use npm run envpara ver todos eles. Isso está documentado em https://docs.npmjs.com/misc/scripts#environment e não é apenas para scripts de "ciclo de vida", como prepublishtambém qualquer script executado por npm run.

Você pode acessar esses códigos internos (por exemplo, process.env.npm_package_config_portem JS), mas eles já estão disponíveis para o shell que está executando os scripts, para que você também possa acessá-los como $npm_...expansões nos "scripts" (sintaxe unix, pode não funcionar no Windows?).

A seção "config" parece destinada a esse uso:

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

Uma qualidade importante desses campos "config" é que os usuários podem substituí-los sem modificar o 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

Consulte os documentos de configuração do npm e de configuração do fio .
Parece que fio lê ~/.npmrctão npm config setafeta tanto, mas yarn config setescreve ~/.yarnrc, tão somente fio vai vê-lo :-(

Beni Cherniavsky-Paskin
fonte
1

A resposta de @ luke foi quase a que eu precisava! Obrigado.

Como a resposta selecionada é muito direta (e correta), mas antiga, gostaria de oferecer uma alternativa para importar variáveis ​​de um arquivo .env separado ao executar seus scripts e corrigir algumas limitações na resposta de Luke. Tente o seguinte:

::: arquivo .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"

Então, no seu pacote json, você criará um script que definirá as variáveis ​​e executará antes dos scripts necessários:

::: package.json :::

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

Algumas observações:

  • A expressão regular no comando grep'ed cat limpará os comentários e as linhas vazias.

  • O &&não precisa ser "colado" para npm run set-env, como seria necessário se você estava definindo as variáveis no mesmo comando.

  • Se você estiver usando fio, poderá receber um aviso, pode alterá-lo yarn set-envou usá-lo npm run set-env --scripts-prepend-node-path &&.

Ambientes diferentes

Outra vantagem ao usá-lo é que você pode ter diferentes variáveis ​​de ambiente.

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

Por favor, lembre-se de não adicionar arquivos .env ao seu repositório git quando tiver chaves, senhas ou dados pessoais / sensíveis!

Felipe N Moura
fonte