Как установить переменные окружения из package.json


313

Как установить некоторые переменные среды изнутри package.jsonдля использования с npm startподобными командами?

Вот что у меня сейчас есть в моем package.json:

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

Я хочу установить переменные окружения (например NODE_ENV) в сценарии запуска, но при этом запускать приложение можно всего одной командой npm start.


Вы можете прочитать этот ответ stackoverflow.com/a/57509175/11127383
Даниэль Даниелецкий

Ответы:


436

Установите переменную среды в команде сценария:

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

Тогда используйте process.env.NODE_ENVв своем приложении.

Примечание: envгарантирует, что он работает на разных платформах. Вы можете опустить его, если заботитесь только о Mac / Linux.


65
Кто-нибудь разобрался с альтернативой для окон ..?
бесконечность

65
@infinity использует cross-env и очень прост в использовании.
mikekidder

106
@infinity use set NODE_ENV=test&& mocha --reporter spec- между тестом и && специально нет пробела.
Джейми Пенни

18
"test": "NODE_ENV=test mocha --reporter spec"не будет работать в системах Windows.
Бенни Нойгебауэр

7
@infinity @ jamie-penney env NODE_ENV=test mocha --reporter specбудет использовать объявленную переменную окружения в кроссплатформенном режиме, но ключ в том, что она используется npm в одноразовом режиме, только для выполнения сценария npm. (Он не установлен или не экспортируется для использования в будущем.) Пока вы запускаете команду из сценария npm, проблем нет. Кроме того, "&&" должен быть удален при этом.
Estaples

219

Просто используйте кросс-env пакета NPM . Супер просто. Работает на 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Переменная будет установлена перекрестная окр


Тройные обратные "test": "cross-env TS_NODE_COMPILER_OPTIONS='{\\\"module\\\":\\\"commonjs\\\"}' mocha"
слеши

1
Лучшее решение, потому что кроссплатформенность.
Бернардн

Может кто-нибудь наконец помочь мне решить, должен ли я использовать envили cross-env? С одной стороны, env не требует от меня установки чего-либо, а с другой cross-env- более популярна. Может кто-нибудь подтвердить, envработает ли на всех платформах?
Ришав

2
@Rishav envне работает как есть на всех платформах, отсюда и причина cross-envсуществования. Просто используйте cross-envи покончите с этим.
ТетраДев

38

Поскольку я часто нахожу себя работающим с несколькими переменными окружения, я считаю полезным хранить их в отдельном .envфайле (не обращайте на это внимания из вашего контроля версий).

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

Затем добавьте export $(cat .env | xargs) &&перед вашей командой сценария.

Пример:

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

Для теста вы можете просмотреть переменные env, запустив npm run env(linux) или npm run env-windows(windows).


1
Очень хорошо, это почти сработало для меня! Я хотел бы добавить несколько комментариев: - У вас не может быть пустых строк в вашем файле .env - Комментарии в вашем файле .env сломают ваш скрипт - Если несколько скриптов используют один и тот же файл .env, вам придется повторить это - Прежде чем &&он заработал, мне пришлось удалить место. Если у вас есть несколько файлов .env, поддерживать его может быть немного сложнее. Ваш ответ вдохновил меня на подготовку этого предложения: stackoverflow.com/questions/25112510/…
Felipe N Moura

37

Я просто хотел добавить свои два цента сюда для будущих исследователей узлов. На моем Ubuntu 14.04 NODE_ENV=testне работал, мне пришлось использовать, export NODE_ENV=testпосле чего NODE_ENV=testтоже начал работать, странно.

В Windows, как уже было сказано, вы должны использовать, set NODE_ENV=testно для кроссплатформенного решения библиотека кросс-env, похоже, не сработала, и вам действительно нужна библиотека для этого:

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

Вертикальные черты нужны, так как в противном случае Windows зависнет по неизвестной export NODE_ENVкоманде: D. Не знаю, о том, что нужно сделать, но я тоже их убрал.


6
Вы использовали &&? NODE_ENV=test yaddaозначает «запустить yadda, установить NODE_ENVвнутри yaddaпеременных среды». NODE_ENV=test && yaddaозначает «установить NODE_ENVв локальной среде, но не экспортировать его, а затем запустить yadda» NODE_ENV=test yadda- это предпочтительный подход.
Джош Келли,

Извините, что некоторое время не проверял мою учетную запись stackoverflow. Но в основном глупая Windows не работала, используя NODE_ENV=test && npm run testчто-то подобное. Я сделал лучшее решение, используя process.env["NODE_ENV"] = "testing";мой файл testhelper.js.
TeemuK

5
@TeemuK, просто чтобы добавить два моих цента, когда вы запускаете команду &&, потеряв переменные окружения, установка переменных окружения без экспорта работает только для текущей команды (что ничего). выполнить команду с переменным окр без экспорта U делать: NODE_ENV=test npm run test. Наконец, причина того, что это сработало после экспорта, заключается в том, что переменная ur теперь доступна (экспортирована) в сеансе, а ваш NODE_ENV без экспорта ничего не делал.
Тарек

19

Попробуйте это в Windows, заменив YOURENV:

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

1
Да! Спасибо! Это был ответ, который я искал! : D
Даниэль Тонон

6
Я должен был удалить пробел перед &&.
Кеннет Солберг

@ Комментарий KennethSolberg был последний штрих , который сделал это для меня (только для Windows)
улу

У меня тоже была проблема с космосом. При регистрации длины строки я мог сказать, что пространство добавлено. Я пытался избежать кавычек - и они действительно хранились в envar. Я пробовал другие разделители безрезультатно. Удаление пробела или обрезка значения, которое мне кажется неправильным, были единственными способами обойти эту проблему.
Нил Гай Линдберг

8

внезапно я обнаружил, что 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;
}

Я был бы очень признателен, если бы принял ответ от кого-то другого, кто знает, как лучше установить переменные окружения в package.json или сценарии инициализации или что-то вроде того, где приложение загружается кем-то другим.


4

Для большего набора переменных среды или когда вы хотите использовать их повторно, вы можете использовать env-cmd.

./.env файл:

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

./package.json:

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

как вы используете ENV1 в сценарии?
ValRob

Обычныйprocess.env.ENV1
KARASZI István

но внутри package.json? Я читал, что это невозможно (?)
ValRob

Я не понимаю Почему ты бы так поступил?
КАРАЗИ Иштван

Возможно, это глупый подход, но я обновил macOs Catalina, и теперь команда mongodb не работает, поэтому мне нужно указать данные / папку mongod --dbpath ~/data/db. Я хочу запустить что-то подобное, npm mongodbи это получит переменную окружения dbpath и запустит mondodb, как всегда ... и ... я хочу поделиться им с другими членами.
ValRob

2

Хотя я не отвечаю прямо на вопрос, я хотел бы поделиться идеей поверх других ответов. Из того, что я получил, каждый из них мог бы предложить некоторый уровень сложности для достижения кроссплатформенной независимости.

В моем сценарии все, что я хотел, первоначально, чтобы установить переменную, чтобы контролировать, защищать ли сервер с помощью аутентификации 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
    }
}

Возможно, это может помочь кому-то еще



2

Это будет работать в консоли Windows :

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

npm run aaa

вывод: test

Смотрите этот ответ для деталей.


5
Должно быть set TMP=test&& npm run bbb. Пробел до &&этого также будет составлять часть NODE_ENVстроки
FisNaN

@FisNaN Не должно быть так, если вы заключите его в кавычки ".
Кайзер

2

используйте git bash в windows. Git Bash обрабатывает команды не так, как cmd.

Большинство командных приглашений Windows будут задыхаться, когда вы устанавливаете переменные среды с NODE_ENV = production, подобным этому. (Исключением является Bash в Windows, который использует собственный Bash.) Аналогичным образом, существует разница в том, как команды Windows и POSIX используют переменные среды. В POSIX вы используете: $ ENV_VAR, а в Windows вы используете% ENV_VAR%. - перекрестный документ

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

используйте пакет dotenv для объявления переменных env


1

Вы не должны устанавливать переменные ENV в package.json. actionhero использует, NODE_ENVчтобы позволить вам изменять параметры конфигурации, которые загружаются из файлов в ./config. Проверьте файл конфигурации redis и посмотрите, как NODE_ENV использует для изменения параметров базы данных вNODE_ENV=test

Если вы хотите использовать другие переменные ENV для настройки (возможно, порт HTTP), вам все равно не нужно ничего менять package.json. Например, если вы установили PORT=1234в ENV и хотите использовать его в качестве порта HTTP NODE_ENV=production, просто укажите это в соответствующем файле конфигурации, IE:

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

здорово. я думаю, что вы не читали мой вопрос ... моя проблема в том, как установить NODE_ENV, а не в том, как его использовать.
dev.meghraj

1
Если вы хотите установить несколько свойств среды, вы не делаете это в npm startкоманде. Используя фрагмент кода выше, если вы хотите запустить сервер с помощью порта ENV было бы: export PORT=1234; npm start. Вы можете добавить столько объявлений ENV, сколько вам нужно, но они не принадлежат файлу package.json. Если вы обеспокоены о том , что они существуют , вы должны использовать по умолчанию в файле конфигурации: port: process.env.PORT || 8080.
Тони

1
Возможно, альтернативным способом объяснить это было бы то, что NODE_ENV (и другие переменные среды) являются частью среды (отсюда и название). Обычно это свойства сервера, на котором вы запускаете приложение, а не ваше приложение. Вы можете установить их вручную с помощью команды, которую вы выполняете, то есть: NODE_ENV=test npm startили установить их с помощью оболочки
Evan

3
Я не согласен. использование ./config для каждой среды ограничивает использование статических сред при развертывании приложения. Это устаревшая философия, которая не позволит вам раскручивать новые типы сред при необходимости. IE для каждой новой среды, которую вы хотите, вам нужно будет добавить .config. Установка переменных среды во время выполнения может быть лучшим вариантом, когда ваш технический стек требует большей гибкости. Я думаю, что ваш ./config был бы хорош для настройки «типов» сред, но ваше приложение было бы более гибким, если бы вы могли определять такие вещи, как строки dsn и конечные точки API во время выполнения.
Джесси Грейтхаус

@JesseGreathouse - у меня есть приложение node.js, и мне нужно установить переменные среды во время выполнения - в каком файле я бы их установил?
Роджер Доджер

1

npm (и пряжа) передает много данных из package.json в сценарии как переменные среды. Используйте, npm run envчтобы увидеть их всех. Это задокументировано в https://docs.npmjs.com/misc/scripts#environment и предназначено не только для сценариев «жизненного цикла», таких как, prepublishно также для любых сценариев, выполняемых npm run.

Вы можете получить доступ к этим внутри кода (например, process.env.npm_package_config_portв JS), но они уже доступны для оболочки, выполняющей сценарии, так что вы также можете обращаться к ним как к $npm_...расширениям в «сценариях» (синтаксис 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 config и документы по конфигурации пряжи .
Похоже, что пряжа читает ~/.npmrcтак npm config setвлияет на обоих, но yarn config setпишет ~/.yarnrc, так что только пряжа будет видеть это :-(


1

Ответ @ Люка был почти тот, который мне был нужен! Спасибо.

Поскольку выбранный ответ очень простой (и правильный), но старый, я хотел бы предложить альтернативу для импорта переменных из отдельного файла .env при запуске ваших сценариев и исправления некоторых ограничений в ответе Люка. Попробуй это:

::: .env file :::

# 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"

Затем в вашем пакете json вы создадите скрипт, который установит переменные и запустит их до того, как вам понадобятся скрипты:

::: package.json :::

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

Некоторые наблюдения:

  • Регулярное выражение в команде grep'ed cat удалит комментарии и пустые строки.

  • &&Не нужно быть «склеены» в npm run set-env, как это было бы необходимо , если вы настраивали переменные в одной команде.

  • Если вы используете пряжу, вы можете увидеть предупреждение, вы можете изменить его 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, если у вас есть ключи, пароли или важные / личные данные!

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.