Отправка аргументов командной строки в npm script
Часть scripts
моего package.json
в настоящее время выглядит следующим образом:
"scripts": {
"start": "node ./script.js server"
}
... что означает, что я могу запустить npm start
, чтобы запустить сервер. Пока все хорошо.
Однако я хотел бы иметь возможность запускать что-то вроде npm start 8080
и передавать аргументы (ов) на script.js
(например, npm start 8080
= > node ./script.js server 8080
). Возможно ли это?
Ответы
Ответ 1
Редактировать 2014.10.30: есть возможность передавать аргументы в npm run
начиная с версии 2.0.0
Синтаксис выглядит следующим образом:
npm run <command> [-- <args>]
Обратите внимание, что необходимо --
. Необходимо разделить параметры, передаваемые самой команде npm
, и параметры, передаваемые вашему сценарию.
Так что если у вас есть в package.json
"scripts": {
"grunt": "grunt",
"server": "node server.js"
}
Тогда следующие команды будут эквивалентны:
grunt task:target
=> npm run grunt -- task:target
node server.js --port=1337
=> npm run server -- --port=1337
Чтобы получить значение параметра, см. Этот вопрос. Для чтения именованных параметров, вероятно, лучше всего использовать библиотеку синтаксического анализа, такую как yargs или minimist; nodejs предоставляет process.argv
глобально, содержащий значения параметров командной строки, но это низкоуровневый API (массив строк, разделенных пробелами, который предоставляется операционной системой для исполняемого файла узла).
Изменить 2013.10.03: в настоящее время это невозможно напрямую. Но на npm
была открыта связанная проблема GitHub для реализации запрашиваемого вами поведения. Кажется, консенсус заключается в том, чтобы это реализовать, но это зависит от другой проблемы, решаемой ранее.
Исходный ответ: В качестве некоторого обходного пути (хотя и не очень удобного) вы можете сделать следующее:
Скажите имя вашего пакета из package.json
myPackage
и у вас также есть
"scripts": {
"start": "node ./script.js server"
}
Затем добавьте в package.json
:
"config": {
"myPort": "8080"
}
И в вашем script.js
:
// defaulting to 8080 in case if script invoked not via "npm run-script" but directly
var port = process.env.npm_package_config_myPort || 8080
Таким образом, по умолчанию npm start
будет использовать 8080. Однако вы можете настроить его (значение будет сохранено npm
во внутренней памяти):
npm config set myPackage:myPort 9090
Затем, при npm start
, будет использоваться 9090 (переопределено значение по умолчанию из package.json
).
Ответ 2
Вы попросили запустить что-то вроде npm start 8080
. Это возможно без необходимости изменять script.js
или файлы конфигурации следующим образом.
Например, в вашем значении "scripts"
JSON включите -
"start": "node ./script.js server $PORT"
И затем из командной строки:
$ PORT=8080 npm start
Я подтвердил, что это работает с использованием bash и npm 1.4.23. Обратите внимание, что для этой работы не требуется GitHub npm проблема № 3494.
Ответ 3
Вы также можете сделать это:
В package.json
:
"scripts": {
"cool": "./cool.js"
}
В cool.js
:
console.log({ myVar: process.env.npm_config_myVar });
В CLI:
npm --myVar=something run-script cool
Должен вывести:
{ myVar: 'something' }
Обновление. Используя npm 3.10.3, кажется, что он уменьшает переменные process.env.npm_config_
? Я также использую better-npm-run
, поэтому я не уверен, что это ванильное поведение по умолчанию или нет, но этот ответ работает. Вместо process.env.npm_config_myVar
попробуйте process.env.npm_config_myVar
Ответ 4
Ответ jakub.g правильный, однако пример использования grunt кажется немного сложным.
Итак, мой простой ответ:
- Отправка аргумента командной строки на номер npm script
Синтаксис для отправки аргументов командной строки в npm script:
npm run [command] [-- <args>]
Представьте, что у нас есть задача запуска npm в нашем пакете. json запускает сервер webpack dev:
"scripts": {
"start": "webpack-dev-server --port 5000"
},
Мы запускаем это из командной строки с помощью npm start
Теперь, если мы хотим передать в порт номер npm script:
"scripts": {
"start": "webpack-dev-server --port process.env.port || 8080"
},
запуск этого и передача порта, например. 5000 через командную строку:
npm start --port:5000
- Использование package.json config:
Как уже упоминалось jakub.g, вы можете альтернативно установить параметры в config вашего package.json
"config": {
"myPort": "5000"
}
"scripts": {
"start": "webpack-dev-server --port process.env.npm_package_config_myPort || 8080"
},
npm start
будет использовать порт, указанный в вашей конфигурации, или, альтернативно, вы можете отменить его
npm config set myPackage:myPort 3000
- установка параметра в вашем номере npm script
Пример чтения переменной, установленной в вашем номере npm script. В этом примере NODE_ENV
"scripts": {
"start:prod": "NODE_ENV=prod node server.js",
"start:dev": "NODE_ENV=dev node server.js"
},
прочитайте NODE_ENV в server.js либо prod, либо dev
var env = process.env.NODE_ENV || 'prod'
if(env === 'dev'){
var app = require("./serverDev.js");
} else {
var app = require("./serverProd.js");
}
Ответ 5
npm поддержка 2.x cli args
Команда
npm run-script start -- --foo=3
Package.json
"start": "node ./index.js"
index.js
console.log('process.argv', process.argv);
Ответ 6
Используйте process.argv
в своем коде, а затем просто добавьте конечный $*
для ввода значения ваших скриптов.
В качестве примера попробуйте это с помощью простого скрипта, который просто записывает предоставленные аргументы в стандартный echoargs.js
:
console.log('arguments: ' + process.argv.slice(2));
package.json:
"scripts": {
"start": "node echoargs.js $*"
}
Примеры:
> npm start 1 2 3
arguments: 1,2,3
process.argv[0]
- исполняемый файл (узел), process.argv[1]
- ваш скрипт.
Протестировано с npm v5.3.0 и узлом v8.4.0
Ответ 7
Если вы хотите передать аргументы в середине npm script, а не просто добавить их в конец, тогда встроенные переменные среды, похоже, будут работать красиво:
"scripts": {
"dev": "BABEL_ARGS=-w npm run build && cd lib/server && nodemon index.js",
"start": "npm run build && node lib/server/index.js",
"build": "mkdir -p lib && babel $BABEL_ARGS -s inline --stage 0 src -d lib",
},
Здесь npm run dev
передает флаг -w
watch, но npm run start
запускает регулярную сборку один раз.
Ответ 8
Это не отвечает на ваш вопрос, но вы всегда можете использовать переменные среды:
"scripts": {
"start": "PORT=3000 node server.js"
}
Затем в файле server.js:
var port = process.env.PORT || 3000;
Ответ 9
Из того, что я вижу, люди используют сценарии package.json, когда они хотели бы запустить script более простым способом. Например, чтобы использовать nodemon
, установленный в локальном node_modules, мы не можем вызвать nodemon
непосредственно из cli, но мы можем вызвать его, используя ./node_modules/nodemon/nodemon.js
. Итак, чтобы упростить эту длинную типизацию, мы можем поместить это...
...
scripts: {
'start': 'nodemon app.js'
}
...
... затем вызовите npm start
, чтобы использовать 'nodemon', который имеет app.js в качестве первого аргумента.
Что я хочу сказать, если вы просто хотите запустить свой сервер с помощью команды node
, я не думаю, что вам нужно использовать scripts
. Ввод npm start
или node app.js
имеет те же самые усилия.
Но если вы хотите использовать nodemon
и хотите передать динамический аргумент, не используйте script
. Вместо этого попробуйте использовать символическую ссылку.
Например, с использованием миграции с sequelize
. Я создаю символическую ссылку...
ln -s node_modules/sequelize/bin/sequelize sequelize
... И я могу передать любые аргументы, когда я это называю...
./sequlize -h /* show help */
./sequelize -m /* upgrade migration */
./sequelize -m -u /* downgrade migration */
и т.д...
На этом этапе использование символической ссылки - лучший способ понять, но я не думаю, что это лучшая практика.
Я также надеюсь на ваше мнение на мой ответ.
Ответ 10
Я нашел этот вопрос, когда пытался решить свою проблему с помощью команды sequelize seed: generate cli:
node_modules/.bin/sequelize seed:generate --name=user
Позвольте мне перейти к сути. Я хотел иметь короткую команду сценария в моем файле package.json и одновременно указывать аргумент --name
Ответ пришел после нескольких экспериментов. Вот моя команда в package.json
"scripts: {
"seed:generate":"NODE_ENV=development node_modules/.bin/sequelize seed:generate"
}
... а вот и пример запуска его в терминале для генерации начального файла для пользователя
> yarn seed:generate --name=user
> npm run seed:generate -- --name=user
FYI
yarn -v
1.6.0
npm -v
5.6.0
Ответ 11
npm run script_target - <аргумент> По сути, это способ передачи аргументов командной строки, но он будет работать только в том случае, если в скрипте запущена только одна команда, например, я запускаю команду, т.е. npm run start - 4200
"script":{
"start" : "ng serve --port="
}
Это будет выполняться для передачи параметров командной строки, но что если мы запустим более одной команды вместе, например, npm, запустите build c: /workspace/file
"script":{
"build" : "copy c:/file <arg> && ng build"
}
но он будет интерпретироваться следующим образом при выполнении копии c: /file && ng build c: /work space/file, и мы ожидаем что-то вроде этой копии c: /file c: /work space/file && ng build
Примечание: - поэтому параметр командной строки работает только в том случае, если в сценарии только одна команда.
Я прочитал некоторые ответы выше, в которых некоторые из них пишут, что вы можете получить доступ к параметру командной строки, используя символ $, но это не сработает