Кроссплатформенный способ передачи переменных среды в качестве аргументов в сценарии npm - PullRequest
0 голосов
/ 05 октября 2018

В Windows или Linux я хочу передать аргументы в npm script, но сделать так, чтобы они вводились как переменные среды

Из командной строки я бы начал свой проект таким способом:

npm run start -- --env=dev --host=localhost --port=1234

Чтобы использовать мои аргументы и вводить их как переменные env независимо от платформы, я использовал пакет cross-env npm:

package.json

  "scripts": {
    "start": "cross-env env=%env% host=%host% port=%port% my-app"
  },

Я понимаю, что вышеприведенный код является недопустимым синтаксисом, но может ли этот сценарий start каким-то образом потреблять передаваемые мною аргументы вместо их перенаправления на my-app?

1 Ответ

0 голосов
/ 05 октября 2018

К сожалению, npm не предоставляет и не собирается предоставлять встроенную функцию, позволяющую передавать аргументы в середину сценария npm (как указано здесь ) .Аргументы могут быть переданы только в конец скрипта.

Для Linux и macOS вы можете использовать функции bash в npm-скриптах для передачи аргументов в середину скрипта, согласно моемуответ здесь .Однако Windows захлебнется таким решением.

Поскольку кросс-платформенная совместимость является требованием, рассмотрите возможность перемещения логики, которая в настоящее время содержится в вашем скрипте start, в отдельный служебный скрипт nodejs.Сценарий nodejs можно затем запустить с помощью npm-скрипта с именем start.

Ниже описано, как выполнить ваше требование кросс-платформенным образом.


1.Пользовательский скрипт утилиты nodejs.

Создайте скрипт nodejs следующим образом.Давайте назовем скрипт start.js и сохраним его в корне каталога вашего проекта, то есть на том же уровне, где в данный момент находится ваш файл package.json .

const execSync = require('child_process').execSync;

const args = process.argv.splice(2, process.argv.length - 2)
    .map(arg => arg.replace(/^--/, ''));

execSync(`cross-env ${args.join(' ')} my-app`, {stdio:[0, 1, 2]});

Объяснение:

  1. В первой строке мы require встроенные узлы execSync().Мы будем использовать это для запуска cross-env и установки переменных среды.

  2. Встроенные узлы process.argv получают аргументы, передаваемые через командную строку.Первые два элемента в узлах process.argv:

    • Путь к исполняемому файлу, на котором выполняется файл JavaScript.
    • Путь к исполняемому файлу JavaScript.
  3. Однако нас интересуют только элементы третьего элемента в массиве и далее - так как это будут ваши аргументы, передаваемые через CLI.Эти строки, которые читаются;

    const args = process.argv.splice(2, process.argv.length - 2)
        .map(arg => arg.replace(/^--/, ''));
    

    , создают переменную args и назначают массив, содержащий каждый аргумент, передаваемый через CLI.Первые два вышеупомянутых элемента в пункте 2 исключаются из массива методом splice().В методе map() мы удаляем префикс -- из каждого аргумента.

  4. Последнее чтение строки:

    execSync(`cross-env ${args.join(' ')} my-app`, {stdio:[0, 1, 2]});
    

    вызываетcross-env и размещает аргументы в виде строки с использованием литералов шаблона и метода Array join().Часть stdio настраивает каналы для stdin, stdout, stderr в дочернем процессе.

Примечание: Если вы нацеливаетесь на более старые версии узла, которые не поддерживают литералы шаблона , вы можете заменить эту строку на следующую.Это обрабатывает конкатенацию строк с использованием оператора +:

execSync('cross-env ' + args.join(' ') + ' my-app', {stdio:[0, 1, 2]});

Аналогично, если функции стрелок ES6 не поддерживаются, измените map() для использования стандартных функций.Например:

.map(function(arg) {
  return arg.replace(/^--/, '');
});

2.Скрипт package.json.

Переопределите ваш скрипт start в package.json следующим образом:

"scripts": {
  "start": "node start"
},

Здесь мы просим узел вызвать start.js script.

Примечание Если вы предпочитаете сохранить файл start.js в каталоге, который отличается от указанного выше корня вашегокаталог проекта, тогда вам нужно будет указать путь к start.js при необходимости.Путь должен быть относительно package.json .Например:

"scripts": {
  "start": "node ./the/path/to/start"
},

3.Запуск npm-скрипта.

Сценарий npm start может быть вызван через CLI с помощью команды:

$ npm start -- --env=dev --host=localhost --port=1234

Часть run, т. Е. npm run start ... не требуется, когдавызов скрипта npm start.

...