it-swarm.com.ru

Отправка аргументов командной строки в скрипт npm

Часть scripts моего package.json в настоящее время выглядит следующим образом:

"scripts": {
    "start": "node ./script.js server"
}

... что означает, что я могу запустить npm start, чтобы запустить сервер. Все идет нормально.

Однако я хотел бы иметь возможность запускать что-то вроде npm start 8080 и передавать аргументы в script.js (например, npm start 8080 => node ./script.js server 8080). Это возможно?

507
arnemart

Изменить 2014.10.30:Можно передавать аргументы в npm run начиная с npm 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 (массив строк, разделенных пробелами, предоставляемый операционной системой для исполняемого файла узла). 


Edit 2013.10.03: В настоящее время это невозможно напрямую. Но есть связанная проблема GitHub, открытая на npm для реализации запрашиваемого вами поведения. Кажется, консенсус заключается в том, чтобы это реализовать, но это зависит от другой проблемы, решаемой ранее.


Исходный ответ: В качестве некоторого обходного пути (хотя и не очень удобного) вы можете сделать следующее:

Скажите, что ваше имя пакета от 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 переопределяется).

736
jakub.g

Вы просили, чтобы иметь возможность запустить что-то вроде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 .

164
cjerdonek

Вы также можете сделать это:

В 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, поэтому я не уверен, является ли это поведением Vanilla по умолчанию или нет, но этот ответ это работает. Вместо process.env.npm_config_myVar попробуйте process.env.npm_config_myvar

65
francoisrv

jakub.g ответ правильный, однако пример использования grunt кажется немного сложным.

Итак, мой более простой ответ:

- Отправка аргумента командной строки в скрипт npm

Синтаксис для отправки аргументов командной строки в скрипт npm:

npm run [command] [-- <args>]

Представьте, что у нас есть пакет запуска npm в нашем package.json для запуска сервера разработки webpack:

"scripts": {
  "start": "webpack-dev-server --port 5000"
},

Мы запускаем это из командной строки с помощью npm start 

Теперь, если мы хотим передать порт в скрипт npm:

"scripts": {
  "start": "webpack-dev-server --port process.env.port || 8080"
},

запуск этого и прохождение порта, например 5000 через командную строку будет выглядеть следующим образом:

npm start --port:5000

- Использование config.json config:

Как упоминается jakub.g, вы можете альтернативно установить параметры в конфигурации вашего 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

Пример чтения набора переменных в вашем скрипте npm. В этом примере 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");
}
57
steven iseki

поддержка 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);

25
Gregory Houllier

Используйте 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

23
Peter

Если вы хотите передать аргументы в середину сценария npm, а не просто добавлять их в конец, тогда встроенные переменные среды, похоже, будут работать хорошо:

"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 в babel, но npm run start один раз запускает обычную сборку.

13
Dan Ross

Это на самом деле не отвечает на ваш вопрос, но вы всегда можете вместо этого использовать переменные окружения:

"scripts": {
    "start": "PORT=3000 node server.js"
}

Затем в вашем файле server.js:

var port = process.env.PORT || 3000;
5
DrunkenBeetle

Из того, что я вижу, люди используют сценарии package.json, когда они хотели бы запустить сценарий более простым способом. Например, чтобы использовать nodemon, установленный в локальных node_modules, мы не можем вызвать nodemon напрямую из cli, но мы можем вызвать его с помощью ./node_modules/nodemon/nodemon.js. Итак, чтобы упростить эту долгую печать, мы можем поместить это ...

 ...

 сценарии: {
 '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 */

так далее...

На данный момент, использование symlink - лучший способ понять, но я не думаю, что это лучший способ.

Я также надеюсь на ваше мнение на мой ответ.

3
Kiddo

npm run script_target - <аргумент> По сути это способ передачи аргументов командной строки, но он будет работать только в том случае, если в скрипте запущена только одна команда, как я выполняю команду, т.е. npm run start - 4200

"script":{
       "start" : "ng serve --port="
 }

Это будет выполняться для передачи параметров командной строки, но что если мы запустим более одной команды вместе, например npm, запустите сборку c:/workspace/file  

"script":{
       "build" : "copy c:/file <arg> && ng build"
 } 

но он будет интерпретироваться следующим образом при запуске копировать c:/file && ng build c:/рабочее пространство/файл и мы ожидаем что-то вроде этого copy c:/file c:/рабочее пространство/файл && ng build

Примечание: - поэтому параметр командной строки работает только в том случае, если в сценарии только одна команда.

Я прочитал некоторые ответы выше, в которых некоторые из них пишут, что вы можете получить доступ к параметру командной строки, используя символ $, но это не сработает  

0
Sunny Goel

Я нашел этот вопрос, когда пытался решить свою проблему с помощью команды sequelize seed: generate cli:

node_modules/.bin/sequelize seed:generate --name=user

Позвольте мне перейти к сути. Я хотел иметь короткую команду сценария в моем package.json file и одновременно предоставить аргумент --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
0
Serge Seletskyy