Cómo establecer variables de entorno desde package.json

313

¿Cómo configurar algunas variables de entorno desde adentro package.jsonpara usarlas con npm startcomandos similares?

Esto es lo que tengo actualmente en mi package.json:

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

Quiero conjunto de variables de entorno (como NODE_ENV) en el script de inicio sin dejar de ser capaz de iniciar la aplicación con solo un comando, npm start.

dev.meghraj
fuente
Puedes leer esta respuesta stackoverflow.com/a/57509175/11127383
Daniel Danielecki

Respuestas:

434

Establezca la variable de entorno en el comando de script:

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

Luego úsalo process.env.NODE_ENVen tu aplicación.

Nota: envasegura que funcione en todas las plataformas. Puede omitirlo si solo le importa Mac / Linux.

cesar
fuente
65
¿Alguien ha encontrado una alternativa para windows ...?
infinito
65
@infinity usa cross-env y es muy fácil de usar.
mikekidder
106
@infinity use set NODE_ENV=test&& mocha --reporter spec: no hay espacio entre la prueba y && a propósito.
Jamie Penney
18
"test": "NODE_ENV=test mocha --reporter spec"no funcionará en sistemas Windows.
Benny Neugebauer
77
@infinity @ jamie-penney env NODE_ENV=test mocha --reporter specusará la variable de entorno declarada de forma nativa multiplataforma, pero la clave es que npm la usa ad hoc y de una sola vez, solo para la ejecución del script npm. (No está configurado ni exportado para referencia futura). Mientras esté ejecutando su comando desde el script npm, no hay problema. Además, el "&&" debe eliminarse al hacerlo de esta manera.
estaples
219

Simplemente use el paquete NPM cross-env . Muy facil. Funciona en Windows, Linux y todos los entornos. Tenga en cuenta que no utiliza && para pasar a la siguiente tarea. Simplemente configura el entorno y luego comienza la siguiente tarea. Gracias a @mikekidder por la sugerencia en uno de los comentarios aquí.

De la documentación:

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

Tenga en cuenta que si desea establecer varios vars globales, simplemente dígalos en sucesión, seguido de su comando para que se ejecute.

En definitiva, el comando que se ejecuta (usando spawn) es:

webpack --config build/webpack.config.js

La NODE_ENVvariable de entorno se establecerá mediante cross-env

TetraDev
fuente
Las barras invertidas triples se pueden usar para escapar de las comillas requeridas:"test": "cross-env TS_NODE_COMPILER_OPTIONS='{\\\"module\\\":\\\"commonjs\\\"}' mocha"
bvj
1
La mejor solución porque multiplataforma.
bernardn
¿Alguien puede finalmente ayudarme a decidir si debo usar envo cross-env? Por un lado, env no requiere que instale nada y, por otro lado, cross-enves más popular. ¿Alguien puede confirmar si envfunciona en todas las plataformas?
Rishav
2
@Rishav envno funciona como está en todas las plataformas, de ahí la razón de cross-envexistir. Solo utilízalo cross-envy listo.
TetraDev
38

Debido a que a menudo me encuentro trabajando con múltiples variables de entorno, me resulta útil mantenerlas en un .envarchivo separado (asegúrese de ignorar esto desde su control de origen).

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

Luego anteponga export $(cat .env | xargs) &&su comando de script.

Ejemplo:

{
  ...
  "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 una prueba, puede ver las variables env ejecutando npm run env(linux) o npm run env-windows(windows).

Luke
fuente
1
Muy bien, ¡casi hizo el trabajo por mí! Me gustaría agregar algunos comentarios: - No puede tener líneas vacías en su archivo .env - Los comentarios en su archivo .env romperán su secuencia de comandos - Si varias secuencias de comandos usan el mismo archivo .env, tendrá que repetir eso - Tuve que eliminar el espacio antes &&para que funcione: si tiene varios archivos .env, puede ser un poco más difícil de mantener. Su respuesta me inspiró a preparar esta sugerencia: stackoverflow.com/questions/25112510/…
Felipe N Moura
37

Solo quería agregar mis dos centavos aquí para futuros exploradores de nodos. En mi Ubuntu 14.04 NODE_ENV=testno funcionó, tuve que usarlo y export NODE_ENV=testluego NODE_ENV=testcomenzó a funcionar también, raro.

En Windows, como se ha dicho, debe usar, set NODE_ENV=testpero para una solución multiplataforma, la biblioteca cross-env no pareció funcionar y realmente necesita una biblioteca para hacer esto:

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

Las barras verticales son necesarias ya que de lo contrario Windows se bloquearía con el export NODE_ENVcomando no reconocido : D. No sé sobre el espacio final, pero solo para asegurarme de que también los eliminé.

TeemuK
fuente
66
¿Usaste &&? NODE_ENV=test yaddamedios "correr yadda, estableciendo NODE_ENVdentro yadda. 's variables de entorno NODE_ENV=test && yaddasignifica 'establecer NODE_ENVdentro del entorno local, pero no lo exportan, a continuación, ejecute yadda'. NODE_ENV=test yaddaes el método preferido.
Josh Kelley
Lo siento, no he revisado mi cuenta de stackoverflow en mucho tiempo. Pero, básicamente, Windows tonto no funcionaba con NODE_ENV=test && npm run testalgo similar. Hice una mejor solución usando process.env["NODE_ENV"] = "testing";dentro de mi archivo testhelper.js.
TeemuK el
55
@TeemuK solo para agregar mis dos centavos también, cuando ejecuta su comando con &&las variables de entorno perdidas, establecer las variables de entorno sin exportación funciona solo en el comando actual (que no es nada). para ejecutar el comando con la variable de entorno sin exportar u hacer: NODE_ENV=test npm run test. Finalmente, la razón por la que funcionó después de exportar, es porque su variable ahora está disponible (exportada) en la sesión, su NODE_ENV sin exportación no estaba haciendo nada.
Tarek
19

Pruebe esto en Windows reemplazando YOURENV:

  {
    ...
     "scripts": {
       "help": "set NODE_ENV=YOURENV && tagove help",
       "start": "set NODE_ENV=YOURENV && tagove start"
     }
    ...
  }
Pascal Mayr
fuente
1
¡Si! ¡Gracias! Esta fue la respuesta que estaba buscando! : D
Daniel Tonon
66
Tuve que quitar el espacio antes de &&.
Kenneth Solberg el
El comentario de @ KennethSolberg fue el toque final que lo hizo funcionar para mí (solo Windows)
ulu
Yo también tuve el problema del espacio. Al registrar la longitud de la cadena, podría decir que se agrega el espacio. Probé las comillas escapadas, y en realidad se almacenaron en el envar. Probé otros delimitadores en vano. Eliminar el espacio o recortar el valor, lo que me parece incorrecto, era la única forma de solucionar este problema.
Neil Guy Lindberg
8

de repente descubrí que actionhero está usando el siguiente código, que resolvió mi problema simplemente pasando la --NODE_ENV=productionopción de comando de inicio de script.

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

Realmente agradecería aceptar la respuesta de otra persona que conozca mejor la forma de configurar las variables de entorno en package.json o init script o algo así, donde la aplicación ha sido arrancada por otra persona.

dev.meghraj
fuente
4

Para un conjunto más grande de variables de entorno o cuando desee reutilizarlas, puede usarlas env-cmd.

./.env expediente:

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

./package.json:

{
  "scripts": {
    "test": "env-cmd mocha -R spec"
  }
}
KARASZI István
fuente
¿Cómo usas ENV1 en el script?
ValRob
Lo habitualprocess.env.ENV1
KARASZI István
pero, dentro del paquete.json? había leído que es imposible (?)
ValRob
No entiendo. ¿Por qué harías eso?
KARASZI István
quizás es un enfoque tonto, pero había actualizado MacOs Catalina y ahora el comando mongodb no funciona, así que necesito especificar los datos / carpeta mongod --dbpath ~/data/db. Quiero ejecutar algo así npm mongodby eso obtendrá la variable de entorno dbpath y ejecutará el mondodb como siempre ... y ... quiero compartirlo con otros miembros.
ValRob
2

Aunque no estoy respondiendo directamente a la pregunta, me gustaría compartir una idea además de las otras respuestas. De lo que obtuve, cada uno de estos ofrecería cierto nivel de complejidad para lograr una independencia de plataforma cruzada.

En mi caso, todo lo que quería, originalmente, era establecer una variable para controlar si proteger o no el servidor con autenticación JWT (para fines de desarrollo)

Después de leer las respuestas, decidí simplemente crear 2 archivos diferentes, con la autenticación activada y desactivada respectivamente.

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

Los archivos son simplemente envoltorios que llaman al archivo index.js original (al que le cambié el nombre 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
    }
}

Quizás esto pueda ayudar a alguien más

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

Esto funcionará en la consola de Windows :

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

npm run aaa

salida: test

Vea esta respuesta para más detalles.

Sergey
fuente
55
Debe ser set TMP=test&& npm run bbb. El espacio antes &&también cound como parte de la continuación NODE_ENVde cadena
FisNaN
@FisNaN No debería ser el caso si lo rodea con comillas ".
Kaiser
2

usa git bash en windows. Git Bash procesa los comandos de manera diferente que cmd.

La mayoría de las indicaciones de comando de Windows se ahogarán cuando establezca variables de entorno con NODE_ENV = producción como esa. (La excepción es Bash en Windows, que usa Bash nativo). Del mismo modo, hay una diferencia en cómo Windows y los comandos POSIX utilizan variables de entorno. Con POSIX, usa: $ ENV_VAR y en las ventanas usa% ENV_VAR%. - documento cross-env

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

use el paquete dotenv para declarar las variables env

Shubham Shaw
fuente
1

No debe establecer variables ENV en package.json. actionhero utiliza NODE_ENVpara permitirte cambiar las opciones de configuración que se cargan desde los archivos en ./config. Mira el archivo de configuración de redis y vea cómo se utiliza NODE_ENV para cambiar las opciones de la base de datos enNODE_ENV=test

Si desea usar otras variables ENV para configurar cosas (tal vez el puerto HTTP), aún no necesita cambiar nada package.json. Por ejemplo, si configura PORT=1234en ENV y desea usarlo como el puerto HTTP NODE_ENV=production, solo haga referencia a eso en el archivo de configuración relevante, IE:

# in config/servers/web.js
exports.production = { 
  servers: {
    web: function(api){
      return {
       port: process.env.PORT
      }
    }
  }
}
Evan
fuente
Excelente. Creo que no leíste mi pregunta ... mi problema es cómo configurar NODE_ENV, no para qué sirve.
dev.meghraj
1
Si desea establecer varias propiedades de entorno, no lo haga en el npm startcomando. Utilizando el fragmento anterior, si desea ejecutar el servidor a través del puerto ENV sería: export PORT=1234; npm start. Puede agregar tantas declaraciones ENV como necesite, pero no pertenecen al archivo package.json. Si usted está preocupado acerca de asegurarse de que existan se debe utilizar por defecto en el fichero de configuración: port: process.env.PORT || 8080.
Tony
1
Quizás una forma alternativa de explicar esto sería que NODE_ENV (y otras variables de entorno) son parte del entorno (de ahí el nombre). Por lo general, son propiedades del servidor en el que está ejecutando la aplicación en lugar de su aplicación. Puede configurarlos manualmente a través del comando que ejecute, es decir: NODE_ENV=test npm starto configurarlos mediante el shell
Evan
3
Estoy en desacuerdo. el uso de ./config para cada entorno lo limita a usar entornos estáticos cuando implementa su aplicación. Esta es una filosofía obsoleta que no le permitirá crear nuevos tipos de entornos cuando sea necesario. IE para cada nuevo entorno que desee, deberá agregar un .config. Establecer variables de entorno en tiempo de ejecución puede ser una opción superior cuando su pila de tecnología requiere más flexibilidad. Creo que su ./config sería bueno para configurar "tipos" de entornos, pero su aplicación sería más flexible si pudiera definir cosas como cadenas dsn y puntos finales de API en tiempo de ejecución.
Jesse Greathouse
@JesseGreathouse: tengo una aplicación node.js y necesito configurar las variables de entorno en tiempo de ejecución: ¿en qué archivo las configuraría?
Roger Dodger
1

npm (e yarn) pasa muchos datos de package.json a scripts como variables de entorno. Use npm run envpara verlos a todos. Esto está documentado en https://docs.npmjs.com/misc/scripts#environment y no es solo para scripts de "ciclo de vida", prepublishsino también para cualquier script ejecutado por npm run.

Puede acceder a estos códigos internos (por ejemplo, process.env.npm_package_config_porten JS), pero ya están disponibles para el shell que ejecuta los scripts, por lo que también puede acceder a ellos como $npm_...expansiones en los "scripts" (¿la sintaxis de Unix podría no funcionar en Windows?).

La sección "config" parece destinada a este 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/"
  } 

Una cualidad importante de estos campos de "configuración" es que los usuarios pueden anularlos sin modificar 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

Ver npm config y yarn config docs.
Parece que el hilo se lee ~/.npmrcde manera npm config setafecta a ambos, pero yarn config setescribe a ~/.yarnrc, por lo que sólo hilo de lo verá :-(

Beni Cherniavsky-Paskin
fuente
1

¡La respuesta de @ luke fue casi la que necesitaba! Gracias.

Como la respuesta seleccionada es muy sencilla (y correcta), pero antigua, me gustaría ofrecer una alternativa para importar variables desde un archivo separado .env al ejecutar sus scripts y corregir algunas limitaciones a la respuesta de Luke. Prueba esto:

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

Luego, en su paquete json, creará un script que establecerá las variables y lo ejecutará antes de los scripts que los necesita:

::: package.json :::

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

Algunas observaciones

  • La expresión regular en el comando grep'ed cat borrará los comentarios y las líneas vacías.

  • El &&no necesita ser "pegado" a npm run set-env, ya que se requeriría si estuviera configurando las variables en el mismo comando.

  • Si está utilizando hilo, puede ver una advertencia, puede cambiarlo yarn set-envo usarlo npm run set-env --scripts-prepend-node-path &&.

Diferentes ambientes

Otra ventaja al usarlo es que puede tener diferentes variables de entorno.

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

¡Recuerde no agregar archivos .env a su repositorio git cuando tenga claves, contraseñas o datos sensibles / personales en ellos!

Felipe N Moura
fuente