Как установить переменные окружения из package.json [Node.js]
Как установить некоторые переменные окружения изнутри package.json
использоваться с npm start
как команды
Вот что у меня сейчас есть в моем package.json
:
{
...
"scripts": {
"help": "tagove help",
"start": "tagove start"
}
...
}
Здесь я хочу установить переменные среды (например, NODE_ENV
) в сценарии запуска, все еще имея возможность запустить приложение одной командой, npm start
,
23 ответа
Установите переменную среды в команде сценария:
...
"scripts": {
"start": "node app.js",
"test": "NODE_ENV=test mocha --reporter spec"
},
...
Тогда используйте process.env.NODE_ENV
в вашем приложении.
Примечание. Это только для Mac и Linux. Для Windows обратитесь к комментариям.
Просто используйте пакет 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
переменная окружения будет установлена перекрестным env
Поскольку я часто нахожу себя работающим с несколькими переменными среды, я считаю полезным хранить их в отдельном .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
(окна).
Я просто хотел добавить свои два цента сюда для будущих исследователей узлов. На моем 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. Не знаю, о том, что нужно сделать, но я тоже их убрал.
Попробуйте это в Windows, заменив YOURENV:
{
...
"scripts": {
"help": "set NODE_ENV=YOURENV&& tagove help",
"start": "set NODE_ENV=YOURENV&& tagove start"
}
...
}
Ответ @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, если у вас есть ключи, пароли или важные / личные данные!
Для большего набора переменных среды или когда вы хотите их повторно использовать, вы можете использовать env-cmd
.
./.env
файл:
# This is a comment
ENV1=THANKS
ENV2=FOR ALL
ENV3=THE FISH
./package.json
:
{
"scripts": {
"test": "env-cmd mocha -R spec"
}
}
Npm (и yarn) передает большое количество данных из package.json в скрипты в качестве переменных среды. Использоватьnpm run env
чтобы увидеть их всех. Это задокументировано в https://docs.npmjs.com/misc/scripts и относится не только к сценариям "жизненного цикла", например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 и yarn.
Похоже, что пряжа читает ~/.npmrc
так npm config set
влияет на оба, но yarn config set
пишет в ~/.yarnrc
, поэтому его увидит только пряжа:-(
Если для переменной среды задано значение «production», все devDependencies в вашем
package.json
файл будет полностью проигнорирован при запуске npm install. Вы также можете обеспечить это с помощью
--production
флаг:
npm install --production
Для настройки вы можете использовать любой из этих способов
метод 1: установить для всех узловых приложений
Windows
:
set NODE_ENV=production
Linux, macOS or other unix
основанная система:
export NODE_ENV=production
Это устанавливает NODE_ENV для текущего сеанса bash, поэтому для любых приложений, запущенных после этого оператора, будет установлено значение NODE_ENV для производства.
метод 2: установить для текущего приложения
NODE_ENV=production node app.js
Это установит
NODE_ENV
только для текущего приложения. Это помогает, когда мы хотим протестировать наши приложения в разных средах.
метод 3: создать
.env
файл и использовать его
Здесь используется идея, описанная здесь. Обратитесь к этому сообщению для более подробного объяснения.
По сути, вы создаете файл .env и запускаете несколько сценариев bash, чтобы установить их в среде.
Чтобы избежать написания сценария bash, можно использовать пакет env-cmd для загрузки переменных среды, определенных в файле .env.
env-cmd .env node app.js
метод 4: использование
cross-env package
Этот пакет позволяет устанавливать переменные среды одним способом для каждой платформы.
После установки с помощью npm вы можете просто добавить его в свой сценарий развертывания в package.json следующим образом:
"build:deploy": "cross-env NODE_ENV=production webpack"
Это будет работать в консоли Windows:
"scripts": {
"aaa": "set TMP=test && npm run bbb",
"bbb": "echo %TMP%"
}
npm run aaa
выход:test
Смотрите этот ответ для деталей.
Для одной переменной среды
"scripts": {
"start": "set NODE_ENV=production&& node server.js"
}
Для нескольких переменных среды
"scripts": {
"start": "set NODE_ENV=production&& set PORT=8000&& node server.js"
}
Вдруг я обнаружил, что 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 или сценарии инициализации или что-то вроде того, где приложение загружается кем-то другим.
Используйте 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
Запуск скрипта node.js из package.json с несколькими переменными среды:
- файл package.json:
{
...
"scripts": {
"start": "ENV NODE_ENV=production someapp --options"
}
...
}
Самое элегантное и портативное решение:
package.json
:
"scripts": {
"serve": "export NODE_PRESERVE_SYMLINKS_MAIN=1 && vue-cli-service serve"
},
Под
windows
Создайте
export.cmd
и положите его где-нибудь в свой
%PATH%
:
@echo off
set %*
Если вы:
- В настоящее время используют Windows;
- Установите git bash;
- Не хочу использовать
set ENV
в вашем package.json, что делает его доступным только для машин Windows dev;
Затем вы можете установить оболочку сценария узла с cmd на git bash и написать операторы настройки env в стиле Linux вpackage.json
чтобы он работал как на Windows/Linux/Mac.
$ npm config set script-shell "C:\\Program Files\\git\\bin\\bash.exe"
Хотя я не отвечаю прямо на вопрос, я бы хотел поделиться идеей поверх других ответов. Из того, что я получил, каждый из них мог бы предложить некоторый уровень сложности для достижения кроссплатформенной независимости.
В моем сценарии все, что я хотел, первоначально, чтобы установить переменную для контроля, защищать ли сервер с помощью аутентификации 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
}
}
Возможно, это может помочь кому-то еще
Вы не должны устанавливать переменные 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
}
}
}
}
В дополнение к использованиюcross-env
как описано выше, для установки нескольких переменных среды вpackage.json
«запустить скрипт», если ваш скрипт включает запуск NodeJS, вы можете установить для Node значение pre-require:
{
scripts: {
"eg:js": "node -r dotenv/config your-script.js",
"eg:ts": "ts-node -r dotenv/config your-script.ts",
"test": "ts-node -r dotenv/config -C 'console.log(process.env.PATH)'",
}
}
Это заставит ваш интерпретатор узла потребоватьdotenv/config
, который сам прочитает файл в текущем рабочем каталоге, из которого был вызван node.
The .env
формат нестрогий или либеральный:
# Comments are permitted
FOO=123
BAR=${FOO}
BAZ=Basingstoke Round About
#Blank lines are no problem
Переменные среды не имеют отношения к вашему приложению узла! Единственная роль 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.
Не принимайте близко к сердцу!
Использование Crossenv, вероятно, будет лучшим выбором, как уже было сказано здесь.
Возможно, вы захотите попробовать использовать новый Bun.sh для сложных сценариев. Мне удалось значительно почистить свои скрипты package.json, и я даже могу использовать машинописные скрипты. Это здорово.
булочка запустить index.js
"scripts": {
"start": "bun run src/scripts/index.ts",
"dev": "bun run --watch src/scripts/index.ts",
"simple": "cross-env NODE_ENV=production start "
},
Примечание. Чтобы установить несколько переменных среды, сценарий должен выглядеть следующим образом
"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",
},