Comment définir des variables d'environnement à partir de package.json

313

Comment définir certaines variables d'environnement de l'intérieur package.jsonà utiliser avec des npm startcommandes similaires?

Voici ce que j'ai actuellement dans mon package.json:

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

Je veux définir des variables d'environnement (comme NODE_ENV) dans le script de démarrage tout en étant en mesure de démarrer l'application avec une seule commande, npm start.

dev.meghraj
la source
Vous pouvez lire cette réponse stackoverflow.com/a/57509175/11127383
Daniel Danielecki

Réponses:

436

Définissez la variable d'environnement dans la commande de script:

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

Utilisez ensuite process.env.NODE_ENVdans votre application.

Remarque: envgarantit qu'il fonctionne sur toutes les plateformes. Vous pouvez l'omettre si vous ne vous souciez que de Mac / Linux.

cesar
la source
65
Quelqu'un a-t-il trouvé une alternative pour Windows ..?
infini
65
@infinity utilise cross-env et est très facile à utiliser.
mikekidder
106
@infinity use set NODE_ENV=test&& mocha --reporter spec- il n'y a pas d'espace entre le test et && exprès.
Jamie Penney
18
"test": "NODE_ENV=test mocha --reporter spec"ne fonctionnera pas sur les systèmes Windows.
Benny Neugebauer
7
@infinity @ jamie-penney env NODE_ENV=test mocha --reporter specutilisera la variable d'environnement déclarée de manière native multiplateforme, mais la clé est qu'elle est utilisée par npm de manière ponctuelle et ponctuelle, juste pour l'exécution du script npm. (Il n'est pas défini ou exporté pour référence future.) Tant que vous exécutez votre commande à partir du script npm, il n'y a aucun problème. En outre, le "&&" doit être supprimé lorsque vous procédez de cette manière.
estaples
219

Utilisez simplement le package NPM cross-env . Super facile. Fonctionne sur Windows, Linux et tous les environnements. Notez que vous n'utilisez pas && pour passer à la tâche suivante. Vous venez de définir l'env puis de démarrer la tâche suivante. Crédit @mikekidder pour la suggestion dans l' un des commentaires ici.

De la documentation:

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

Notez que si vous souhaitez définir plusieurs variables globales, vous devez simplement les indiquer successivement, suivi de votre commande à exécuter.

En fin de compte, la commande qui est exécutée (en utilisant spawn) est:

webpack --config build/webpack.config.js

La NODE_ENVvariable d'environnement sera définie par cross-env

TetraDev
la source
Des barres obliques inverses triples peuvent être utilisées pour échapper aux citations requises:"test": "cross-env TS_NODE_COMPILER_OPTIONS='{\\\"module\\\":\\\"commonjs\\\"}' mocha"
bvj
1
Meilleure solution car multi-plateformes.
bernardn
Quelqu'un peut-il enfin m'aider à décider si je dois utiliser envou cross-env? D'une part, env ne me demande pas d'installer quoi que ce soit et d'autre part cross-envest plus populaire. Quelqu'un peut-il confirmer s'il envfonctionne sur toutes les plateformes?
Rishav
2
@Rishav envne fonctionne pas tel quel sur toutes les plateformes, d'où la raison cross-envd'exister. Utilisez simplementcross-env et d'en finir.
TetraDev
38

Parce que je me retrouve souvent à travailler avec plusieurs variables d'environnement, je trouve utile de les conserver dans un .envfichier séparé (assurez-vous de l'ignorer de votre contrôle de code source).

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

Ajoutez ensuite export $(cat .env | xargs) &&avant votre commande de script.

Exemple:

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

Pour un test, vous pouvez afficher les variables env en exécutant npm run env(linux) ou npm run env-windows(windows).

Luc
la source
1
Très bien, ça a presque fait le boulot pour moi! Je voudrais ajouter quelques commentaires: - Vous ne pouvez pas avoir de lignes vides dans votre fichier .env - Les commentaires dans votre fichier .env briseront votre script - Si plusieurs scripts utilisent le même fichier .env, vous devrez répéter cela - J'ai dû supprimer l'espace avant &&pour que cela fonctionne - Si vous avez plusieurs fichiers .env, il peut être un peu plus difficile à maintenir Votre réponse m'a inspiré pour préparer cette suggestion: stackoverflow.com/questions/25112510/…
Felipe N Moura
37

Je voulais juste ajouter mes deux cents ici pour les futurs explorateurs de nœuds. Sur mon Ubuntu 14.04, NODE_ENV=testcela ne fonctionnait pas, j'ai dû l'utiliser export NODE_ENV=testaprès quoi j'ai NODE_ENV=testcommencé à fonctionner aussi, bizarre.

Sur Windows, comme il a été dit, vous devez utiliser, set NODE_ENV=testmais pour une solution multiplateforme, la bibliothèque cross-env ne semble pas faire l'affaire et avez-vous vraiment besoin d'une bibliothèque pour ce faire:

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

Les barres verticales sont nécessaires car sinon Windows planterait sur la export NODE_ENVcommande non reconnue : D. Je ne sais pas à propos de l'espace de fuite, mais juste pour être sûr que je les ai aussi supprimés.

TeemuK
la source
6
L'avez-vous utilisé &&? NODE_ENV=test yaddades moyens « run yadda, la mise au NODE_ENVsein yadda. de variables d'environnement NODE_ENV=test && yaddasignifie « ensemble NODE_ENVdans l'environnement local, mais ne pas exporter, puis exécutez yadda». NODE_ENV=test yaddaL'approche privilégiée est.
Josh Kelley
Désolé, je n'ai pas vérifié mon compte stackoverflow depuis un moment. Mais fondamentalement, Windows n'a pas fonctionné avec NODE_ENV=test && npm run testou quelque chose de similaire. J'ai fait une meilleure solution en utilisant l' process.env["NODE_ENV"] = "testing";intérieur de mon fichier testhelper.js.
TeemuK
5
@TeemuK juste pour ajouter mes deux cents aussi, lorsque vous exécutez votre commande avec &&vous avez perdu vos variables d'environnement, la définition de variables d'environnement sans exportation fonctionne uniquement sur la commande en cours (ce qui n'est rien). pour exécuter la commande avec la variable d'env sans exporter u faire: NODE_ENV=test npm run test. Enfin, la raison pour laquelle cela a fonctionné après avoir exporté, c'est parce que votre variable est désormais disponible (exportée) dans la session, votre NODE_ENV sans exportation ne faisait rien.
Tarek
19

Essayez ceci sous Windows en remplaçant YOURENV:

  {
    ...
     "scripts": {
       "help": "set NODE_ENV=YOURENV && tagove help",
       "start": "set NODE_ENV=YOURENV && tagove start"
     }
    ...
  }
Pascal Mayr
la source
1
Oui! Je vous remercie! C'était la réponse que je cherchais! : D
Daniel Tonon
6
J'ai dû supprimer l'espace avant &&.
Kenneth Solberg
@ Le commentaire de KennethSolberg a été la touche finale qui l'a fait fonctionner pour moi (Windows uniquement)
ulu
Moi aussi, j'ai eu le problème d'espace. Lors de l'enregistrement de la longueur de chaîne, je pouvais dire que l'espace était ajouté. J'ai essayé des citations échappées - et elles étaient en fait stockées dans l'envar. J'ai essayé d'autres délimiteurs en vain. Supprimer l'espace ou rogner la valeur, ce qui me semble mal, était le seul moyen de contourner ce problème.
Neil Guy Lindberg
8

soudain, j'ai trouvé que actionhero utilise le code suivant, qui a résolu mon problème en passant simplement l' --NODE_ENV=productionoption de commande de script de démarrage.

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

j'apprécierais vraiment d'accepter la réponse de quelqu'un d'autre qui connaît mieux la façon de définir les variables d'environnement dans package.json ou le script init ou quelque chose comme, où l'application est amorcée par quelqu'un d'autre.

dev.meghraj
la source
4

Pour un plus grand ensemble de variables d'environnement ou lorsque vous souhaitez les réutiliser, vous pouvez les utiliser env-cmd.

./.env fichier:

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

./package.json:

{
  "scripts": {
    "test": "env-cmd mocha -R spec"
  }
}
KARASZI István
la source
comment utilisez-vous ENV1 dans le script?
ValRob
The usualprocess.env.ENV1
KARASZI István
mais, à l'intérieur du package.json? j'avais lu que
c'était
Je ne comprends pas. Pourquoi ferais-tu ça?
KARASZI István
c'est peut-être une approche stupide, mais j'avais mis à jour les macOs Catalina et maintenant la commande mongodb ne fonctionne pas, donc je dois spécifier les données / dossier mongod --dbpath ~/data/db. Je veux exécuter quelque chose comme npm mongodbet qui obtiendra la variable d'environnement dbpath et exécutera le mondodb comme toujours ... et .. je veux le partager avec d'autres membres.
ValRob
2

Bien que je ne réponde pas directement à la question, je voudrais partager une idée en plus des autres réponses. D'après ce que j'ai obtenu, chacun d'eux offrirait un certain niveau de complexité pour atteindre l'indépendance multiplateforme.

Dans mon scénario, tout ce que je voulais, à l'origine, était de définir une variable pour contrôler la sécurisation ou non du serveur avec l'authentification JWT (à des fins de développement)

Après avoir lu les réponses, j'ai décidé de créer simplement 2 fichiers différents, avec l'authentification activée et désactivée respectivement.

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

Les fichiers sont simplement des wrappers qui appellent le fichier index.js d'origine (que j'ai renommé 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
    }
}

Peut-être que cela peut aider quelqu'un d'autre

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

Cela fonctionnera dans la console Windows :

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

npm run aaa

production: test

Voir cette réponse pour plus de détails.

Sergey
la source
5
Devrait l'être set TMP=test&& npm run bbb. L'espace avant &&sera également lié à la NODE_ENVchaîne
FisNaN
@FisNaN Cela ne devrait pas être le cas si vous l'entourez de guillemets ".
kaiser
2

utilisez git bash dans les fenêtres. Git Bash traite les commandes différemment de cmd.

La plupart des invites de commande Windows s'étouffent lorsque vous définissez des variables d'environnement avec NODE_ENV = production comme ça. (L'exception est Bash sur Windows, qui utilise Bash natif.) De même, il existe une différence dans la façon dont Windows et les commandes POSIX utilisent les variables d'environnement. Avec POSIX, vous utilisez: $ ENV_VAR et sur Windows, vous utilisez% ENV_VAR%. - doc cross-env

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

utiliser le package dotenv pour déclarer les variables env

Shubham Shaw
la source
1

Vous ne devez pas définir de variables ENV dans package.json. actionhero utilise NODE_ENVpour vous permettre de modifier les options de configuration qui sont chargées à partir des fichiers dans ./config. Consultez le fichier de configuration redis et voyez comment NODE_ENV est utilisé pour modifier les options de la base de données dansNODE_ENV=test

Si vous souhaitez utiliser d'autres variables ENV pour définir des choses (peut-être le port HTTP), vous n'avez toujours pas besoin de changer quoi que ce soit package.json. Par exemple, si vous définissez PORT=1234dans ENV et que vous souhaitez l'utiliser comme port HTTP dans NODE_ENV=production, faites simplement référence à cela dans le fichier de configuration correspondant, IE:

# in config/servers/web.js
exports.production = { 
  servers: {
    web: function(api){
      return {
       port: process.env.PORT
      }
    }
  }
}
Evan
la source
génial. Je pense que vous n'avez pas lu ma question. Mon problème est de savoir comment définir NODE_ENV et non son utilisation.
dev.meghraj
1
Si vous souhaitez définir plusieurs propriétés d'environnement, vous ne le faites pas dans la npm startcommande. Utilisation de l'extrait ci - dessus, si vous voulez exécuter votre serveur en utilisant le port ENV ce serait: export PORT=1234; npm start. Vous pouvez ajouter autant de déclarations ENV que vous le souhaitez, mais elles n'appartiennent pas au fichier package.json. Si vous êtes inquiet au sujet de faire en sorte qu'ils vous existez devez utiliser par défaut dans votre fichier de configuration: port: process.env.PORT || 8080.
Tony
1
Une autre façon d'expliquer cela serait peut-être que NODE_ENV (et d'autres variables d'environnement) font partie de l'environnement (d'où le nom). Il s'agit généralement des propriétés du serveur sur lequel vous exécutez l'application plutôt que de votre application. Vous pouvez les définir manuellement via la commande que vous exécutez, c'est-à-dire: NODE_ENV=test npm startou les faire définir par le shell
Evan
3
Je ne suis pas d'accord. l'utilisation d'un ./config pour chaque environnement vous limite à l'utilisation d'environnements statiques lorsque vous déployez votre application. Il s'agit d'une philosophie dépassée qui ne vous permettra pas de créer de nouveaux types d'environnements en cas de besoin. IE pour chaque nouvel environnement que vous souhaitez, vous devrez ajouter un .config. La définition de variables d'environnement au moment de l'exécution peut être une option supérieure lorsque votre pile technologique nécessite plus de flexibilité. Je pense que votre ./config serait bon pour configurer des "types" d'environnements, mais votre application serait plus flexible si vous pouviez définir des choses comme des chaînes dsn et des points finaux api au moment de l'exécution.
Jesse Greathouse
@JesseGreathouse - J'ai une application node.js et je dois définir les variables d'environnement au moment de l'exécution - dans quel fichier dois-je les définir?
Roger Dodger
1

npm (et yarn) transmet de nombreuses données de package.json aux scripts en tant que variables d'environnement. Utilisez npm run envpour les voir tous. Ceci est documenté dans https://docs.npmjs.com/misc/scripts#environment et n'est pas seulement pour les scripts "cycle de vie" comme prepublishmais aussi pour tout script exécuté parnpm run .

Vous pouvez accéder à ces codes internes (par exemple process.env.npm_package_config_portdans JS) mais ils sont déjà disponibles pour le shell exécutant les scripts, vous pouvez donc également y accéder en tant que$npm_... qu'extensions dans les "scripts" (la syntaxe Unix, pourrait ne pas fonctionner sur Windows?).

La section "config" semble destinée à cet usage:

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

Une qualité importante de ces champs "config" est que les utilisateurs peuvent les remplacer sans modifier 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

Voir les documents de configuration de npm et de configuration de fil .
Il semble que le fil lit affecte ~/.npmrcdonc npm config setles deux, mais yarn config setécrit ~/.yarnrc, donc seul le fil le verra :-(

Beni Cherniavsky-Paskin
la source
1

La réponse de @ luke était presque celle dont j'avais besoin! Merci.

Comme la réponse sélectionnée est très simple (et correcte), mais ancienne, je voudrais offrir une alternative pour importer des variables à partir d'un fichier séparé .env lors de l'exécution de vos scripts et corriger certaines limitations de la réponse de Luke. Essaye ça:

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

Ensuite, dans votre package json, vous allez créer un script qui va définir les variables et l'exécuter avant les scripts dont vous avez besoin:

::: package.json :::

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

Quelques observations:

  • L'expression régulière dans la commande grep'ed cat effacera les commentaires et les lignes vides.

  • Le &&ne pas besoin d'être « collé » à npm run set-env, comme il serait nécessaire si vous définissez les variables dans la même commande.

  • Si vous utilisez du fil, un avertissement peut s'afficher, vous pouvez le remplacer par yarn set-envou l'utiliser à la npm run set-env --scripts-prepend-node-path &&place.

Environnements différents

Un autre avantage lors de son utilisation est que vous pouvez avoir différentes variables d'environnement.

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

N'oubliez pas de ne pas ajouter de fichiers .env à votre référentiel git lorsque vous avez des clés, des mots de passe ou des données sensibles / personnelles!

Felipe N Moura
la source