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

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

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

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

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


person dev.meghraj    schedule 04.08.2014    source источник
comment
Вы можете прочитать этот ответ stackoverflow.com/a/57509175/11127383   -  person Daniel Danielecki    schedule 15.08.2019


Ответы (16)


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

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

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

Примечание. Это только для Mac и Linux. Для Windows см. Комментарии.

person cesar    schedule 23.11.2014
comment
Кто-то придумал альтернативу для windows ..? - person infinity; 04.12.2015
comment
@infinity Улучшенный запуск npm решает проблемы межплатформенной совместимости. Однако его конфигурация несколько неуклюжая. - person jokka; 18.12.2015
comment
@infinity использует cross-env и очень проста в использовании. - person mikekidder; 30.01.2016
comment
@infinity use set NODE_ENV=test&& mocha --reporter spec - между тестом и && нет пробела специально. - person Jamie Penney; 22.02.2016
comment
Спасибо @JamiePenney. Мне пришлось удалить пробел перед &&, чтобы заставить его работать. Это почему? `set NODE_ENV = development && (следующая задача) - person TetraDev; 21.05.2016
comment
@TetraDev не могу вспомнить, извини, я думаю, это было включение пробела в вызов набора? - person Jamie Penney; 07.06.2016
comment
cross-env работал у меня за секунды. Подумайте о добавлении его с помощью --save-dev, только если он вам нужен только для теста npm - person Jerico Sandhorn; 01.03.2017
comment
Не работает для npm run-script build. Выданная ошибка 'NODE_ENV' не распознается как внутренняя или внешняя команда, работающая программа или командный файл ' - person Green; 11.04.2017
comment
"test": "NODE_ENV=test mocha --reporter spec" не будет работать в системах Windows. - person Benny Neugebauer; 12.05.2017
comment
@TetraDev Я думаю, у вас будет NODE_ENV, установленный на 'test' (обратите внимание на пробел). Отсутствие пробела - это способ избежать этого, если вы не хотите (или не можете) использовать кавычки. - person Ivan Schwarz; 06.07.2017
comment
Если вы действительно используете cross-env, нет необходимости включать '&&'. Пример: cross-env NODE_ENV=test karma start - person larrydalmeida; 12.08.2017
comment
@infinity @ jamie-penney env NODE_ENV=test mocha --reporter spec будет использовать объявленную переменную среды изначально кроссплатформенным способом, но главное в том, что она используется npm разовым и разовым способом, только для выполнения сценария npm. (Он не устанавливается и не экспортируется для использования в будущем.) Пока вы запускаете команду из сценария npm, проблем нет. Кроме того, при этом необходимо удалить &&. - person estaples; 05.04.2018
comment
Как мы можем добавить несколько переменных env в окнах? - person user2517028; 06.06.2018
comment
если вы хотите использовать env var внутри самого скрипта, вам нужно добавить $, например, если вы запустите mode=prod npm run print и у вас есть скрипт в package.json с именем print "print": "echo environment '$mode'", он напечатает environment 'prod' - person Jonathan Morales Vélez; 24.08.2018
comment
@infinity Несколько переменных среды могут быть установлены в окнах следующим образом: scripts: {start: node index.js, set: env: this: way: env FIRST = one env SECOND = two node index.js}, - person Greg; 21.10.2019
comment
Note: env ensures that it works across platforms. Как? env не является допустимой командой в Windows. - person Timmmm; 24.01.2020
comment
Что за env вы здесь имеете в виду? Вы можете разместить ссылку? - person Qwerty; 27.01.2020
comment
в Windows это работает так: скрипты: {тестирование: cypress open --env CYPRESS_CypressBaseUrl = localhost: 3000} (здесь: npm ›6, node› 13) - person theRealEmu; 06.10.2020
comment
Я хочу использовать файл .env, чтобы у меня были все эти важные детали в одном месте, и чтобы я мог запускать сервер с терминала, или из докера, или docker-compose, или что-то еще. Не считаю это очень полезным ... - person John; 30.06.2021
comment
Как пользователи Windows (в 2021 году) вы можете использовать WSL (подсистему Windows для Linux) для локального запуска моих проектов Node. Это видео https://www.youtube.com/watch?v=lOXatmtBb88 объясняет как настроить VSCode для использования командной строки WSL вместо PowerShell. Это позволяет запускать такие проекты, как https://github.com/mattcarlotta/nextjs-ssr-kit из Windows. Если вы посмотрите на сценарий package.json в этом примере проекта, вы увидите, что он устанавливает переменные среды в командах узла. - person w. Patrick Gale; 06.07.2021

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

person TetraDev    schedule 20.05.2016
comment
Для экранирования обязательных кавычек можно использовать тройную обратную косую черту: "test": "cross-env TS_NODE_COMPILER_OPTIONS='{\\\"module\\\":\\\"commonjs\\\"}' mocha" - person bvj; 08.03.2018
comment
Лучшее решение, потому что кроссплатформенность. - person bernardn; 08.03.2019
comment
Может ли кто-нибудь, наконец, помочь мне решить, следует ли мне использовать env или cross-env? С одной стороны, env не требует от меня ничего устанавливать, а с другой стороны, cross-env более популярен. Может кто-нибудь подтвердить, работает ли env на всех платформах? - person Rishav; 01.04.2020
comment
@Rishav env не работает как есть на всех платформах, отсюда и причина существования cross-env. Просто используйте cross-env и покончим с этим. - person TetraDev; 03.06.2020

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

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

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

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

person TeemuK    schedule 02.04.2016
comment
Вы использовали &&? NODE_ENV=test yadda означает запуск yadda, установка NODE_ENV в переменных среды yadda. NODE_ENV=test && yadda означает установить NODE_ENV в локальной среде, но не экспортировать его, а затем запустить yadda. NODE_ENV=test yadda - предпочтительный подход. - person Josh Kelley; 08.07.2016
comment
Извините, что давно не проверял мою учетную запись stackoverflow. Но в основном глупая Windows не работала с NODE_ENV=test && npm run test или чем-то подобным. Я сделал лучшее решение, используя process.env["NODE_ENV"] = "testing"; в моем файле testhelper.js. - person TeemuK; 03.11.2016
comment
@TeemuK, просто чтобы добавить мои два цента, когда вы запускаете свою команду с &&, вы теряете свои переменные среды, установка переменных среды без экспорта работает только с текущей командой (что ничто). чтобы запустить команду с переменной env без экспорта u do: NODE_ENV=test npm run test. Наконец, причина, по которой он работал после экспорта, заключается в том, что переменная ur теперь доступна (экспортирована) в сеансе, ваш NODE_ENV без экспорта ничего не делал. - person Tarek; 22.02.2017
comment
export и || не распознаются в Windows ... - person Radzor; 11.07.2021

Поскольку я часто работаю с несколькими переменными среды, я считаю полезным хранить их в отдельном файле .env (обязательно игнорируйте это в системе управления версиями). Затем (в Linux) добавьте export $(cat .env | xargs) && в команду сценария перед запуском приложения.

Пример .env файла:

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

Пример index.js:

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

Пример 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",

  }
  ...
}

К сожалению, я не могу установить переменные среды, вызывая сценарий из сценария, например "start-windows": "npm run env-windows && npm start", поэтому в сценариях есть некоторая избыточность.

В качестве теста вы можете увидеть переменные env, запустив npm run env-linux или npm run env-windows, и проверить, попадают ли они в ваше приложение, запустив npm run start-linux или npm run start-windows.

person Luke    schedule 21.02.2019
comment
Очень хорошо, это почти помогло мне! Я хотел бы добавить несколько комментариев: - В вашем файле .env не может быть пустых строк - Комментарии в вашем файле .env нарушат ваш скрипт - Если несколько скриптов используют один и тот же файл .env, вам придется это повторить - Мне пришлось удалить пробел перед &&, чтобы он заработал. Если у вас несколько файлов .env, может быть немного сложнее поддерживать. Ваш ответ вдохновил меня на подготовку этого предложения: stackoverflow.com/questions/25112510/ < / а> - person Felipe N Moura; 06.04.2020
comment
Я не следую сценарию env-windows. Оболочка cmd не распознает ни экспорт, ни xargs. - person Derek Greer; 23.09.2020
comment
Спасибо за уловку @FelipeNMoura и @DerekGreer. Не уверен, почему я думал, что export $(cat .env | xargs) && set работает в Windows. Я переделал сценарий Windows, протестировал его и внес изменения в свой ответ. - person Luke; 16.10.2020

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

  {
    ...
     "scripts": {
       "help": "set NODE_ENV=YOURENV && tagove help",
       "start": "set NODE_ENV=YOURENV && tagove start"
     }
    ...
  }
person Pascal Mayr    schedule 29.11.2018
comment
Мне пришлось удалить пробел перед &&. - person Kenneth Solberg; 09.11.2019
comment
Комментарий @ KennethSolberg был последним штрихом, который заставил его работать для меня (только для Windows) - person ulu; 02.02.2020
comment
У меня тоже была проблема с местом. При регистрации длины строки я мог сказать, что пространство добавлено. Я пробовал экранированные кавычки - и они фактически хранились в envar. Я пробовал другие разделители безрезультатно. Удаление пробела или обрезка значения, что мне кажется неправильным, были единственными способами обойти эту проблему. - person Neil Guy Lindberg; 24.04.2020

внезапно я обнаружил, что actionhero использует следующий код, который решил мою проблему, просто передав --NODE_ENV=production в параметре команды 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;
}

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

person dev.meghraj    schedule 04.08.2014

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

./.env файл:

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

./package.json:

{
  "scripts": {
    "test": "env-cmd mocha -R spec"
  }
}
person KARASZI István    schedule 25.07.2019
comment
как вы используете ENV1 в скрипте? - person ValRob; 15.12.2019
comment
Обычный process.env.ENV1 - person KARASZI István; 16.12.2019
comment
но внутри package.json? я читал, что невозможно (?) - person ValRob; 16.12.2019
comment
Я не понимаю. Почему ты бы так поступил? - person KARASZI István; 16.12.2019
comment
возможно, это глупый подход, но я обновил macOs Catalina, и теперь команда mongodb не работает, поэтому мне нужно указать данные / папку mongod --dbpath ~/data/db. Я хочу запустить что-то вроде npm mongodb, и это получит переменную окружения dbpath и запустит mondodb, как всегда ... и ... я хочу поделиться этим с другими участниками. - person ValRob; 17.12.2019

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

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

npm run aaa

вывод: test

Дополнительные сведения см. В этом ответе.

person Sergey    schedule 19.03.2019
comment
Должно быть set TMP=test&& npm run bbb. Пробел перед && также будет являться частью строки NODE_ENV. - person FisNaN; 27.04.2019
comment
@FisNaN Не должно быть, если вы заключите его в кавычки ". - person kaiser; 04.02.2020
comment
Это работает без пробела перед &&. Итак "scripts": { "aaa": "set TMP=test&& npm run bbb", "bbb": "echo %TMP%" } - person O'Dane Brissett; 22.06.2020
comment
@ O'DaneBrissett Я не могу это проверить прямо сейчас, не стесняйтесь редактировать ответ, если уверены, что он работает в консоли Windows. - person Sergey; 22.06.2020

Ответ @ luke был почти тем, что мне было нужно! Спасибо.

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

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

Затем в своем пакете 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, если в них есть ключи, пароли или конфиденциальные / личные данные!

person Felipe N Moura    schedule 06.04.2020

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

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

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

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

person Shubham Shaw    schedule 30.04.2020

UPDATE: This solution may break in npm v7 due to npm RFC 21


npm (и yarn) передает много данных из 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?).

Кажется, что конфигурационный раздел предназначен для этого использования:

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

Важным качеством этих полей конфигурации является то, что пользователи могут переопределить их, не изменяя package.json!

$ npm run start

> [email protected] 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

> [email protected] start /home/cben/mydir
> node server.js $npm_package_config_port

Serving on localhost:8020

См. конфигурацию npm и yarn config docs.
Похоже, yarn читает ~/.npmrc, поэтому npm config set влияет на оба, но yarn config set записывает в ~/.yarnrc, так что только yarn будет видеть это :-(

person Beni Cherniavsky-Paskin    schedule 31.03.2020
comment
Обратите внимание, что $npm_package_* переменные больше не помещаются в среду автоматически, начиная с версии NPM v7, так что это наверное сломается. - person Dan Dascalescu; 07.01.2021

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

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

Возможно, это поможет кому-то другому

person Luiz Henrique Martins Lins Rol    schedule 17.01.2017

Не следует устанавливать переменные 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
      }
    }
  }
}
person Evan    schedule 04.08.2014
comment
Отлично. Я думаю, вы не читали мой вопрос .. Моя проблема в том, как установить NODE_ENV, а не в том, что от него нужно. - person dev.meghraj; 05.08.2014
comment
Возможно, альтернативным способом объяснить это было бы то, что NODE_ENV (и другие переменные среды) являются частью среды (отсюда и название). Обычно они являются свойствами сервера, на котором выполняется приложение, а не вашего приложения. Вы можете установить их вручную с помощью команды, которую вы выполняете, например: NODE_ENV=test npm start или установить их оболочкой - person Evan; 06.08.2014
comment
Я не согласен. использование ./config для каждой среды ограничивает использование статических сред при развертывании приложения. Это устаревшая философия, которая не позволит вам при необходимости создавать новые типы сред. I.E. для каждой новой среды, которую вы хотите, вам нужно будет добавить файл .config. Установка переменных среды во время выполнения может быть лучшим вариантом, когда ваш технический стек требует большей гибкости. Я думаю, что ваш ./config был бы хорош для настройки типов сред, но ваше приложение было бы более гибким, если бы вы могли определять такие вещи, как строки dsn и конечные точки api во время выполнения. - person Jesse Greathouse; 10.12.2015
comment
@JesseGreathouse - у меня есть приложение node.js, и мне нужно установить переменные среды во время выполнения - в каком файле я бы их установил? - person Roger Dodger; 06.03.2019

Для одной переменной среды

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

Для нескольких переменных среды

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

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

  "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",
  },
person Mabd    schedule 06.12.2020

Переменные среды не имеют отношения к вашему приложению узла! Единственная роль process.env - предоставить вашему приложению переменные системной среды. Если вам нужно добавить переменные среды, вы должны добавить их в свой файл конфигурации docker / vm / vagrant, а не в стартовый скрипт вашего приложения.

Если вы собираетесь передать аргумент экземпляру узла, лучший и единственный способ - использовать node process.argv вместо rocess.env.

Единственный случай, когда вам нужно использовать process.env, - это то, что ваш облачный провайдер применяет некоторые конфигурации, которым должно соответствовать ваше приложение, даже в этом случае они устанавливают переменные среды, а не вы.

Вот как передать аргументы вашему приложению. Вы, наверное, уже знали.

node app.js  port=5000 profile=admin

Потом,

/**
 * 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]
}

Пример сценария:

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

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

Просто попробовал объяснить нюанс между process.env и process.argv.

Не принимайте близко к сердцу!

person Ahmet Emrebas    schedule 25.07.2021