Отправка аргументов командной строки в 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

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

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