К сожалению, 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]});
Объяснение:
В первой строке мы require
встроенные узлы execSync()
.Мы будем использовать это для запуска cross-env
и установки переменных среды.
Встроенные узлы process.argv
получают аргументы, передаваемые через командную строку.Первые два элемента в узлах process.argv
:
- Путь к исполняемому файлу, на котором выполняется файл JavaScript.
- Путь к исполняемому файлу JavaScript.
Однако нас интересуют только элементы третьего элемента в массиве и далее - так как это будут ваши аргументы, передаваемые через CLI.Эти строки, которые читаются;
const args = process.argv.splice(2, process.argv.length - 2)
.map(arg => arg.replace(/^--/, ''));
, создают переменную args
и назначают массив, содержащий каждый аргумент, передаваемый через CLI.Первые два вышеупомянутых элемента в пункте 2 исключаются из массива методом splice()
.В методе map()
мы удаляем префикс --
из каждого аргумента.
Последнее чтение строки:
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
.