Как установить переменные окружения из 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 с несколькими переменными среды:

  1. файл 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, и я даже могу использовать машинописные скрипты. Это здорово.

https://bun.sh/docs/cli/run

булочка запустить 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",
  },
Другие вопросы по тегам