包的脚本部分。Json当前看起来是这样的:
"scripts": {
"start": "node ./script.js server"
}
...这意味着我可以运行npm start来启动服务器。到目前为止一切顺利。
然而,我希望能够运行类似npm start 8080的东西,并将参数传递给script.js(例如npm start 8080 => node ./script.js服务器8080)。这可能吗?
包的脚本部分。Json当前看起来是这样的:
"scripts": {
"start": "node ./script.js server"
}
...这意味着我可以运行npm start来启动服务器。到目前为止一切顺利。
然而,我希望能够运行类似npm start 8080的东西,并将参数传递给script.js(例如npm start 8080 => node ./script.js服务器8080)。这可能吗?
当前回答
我发现这个问题,当我试图解决我的问题运行sequelize seed:generate cli命令:
node_modules/.bin/sequelize seed:generate --name=user
让我言归正传。我想在我的包中有一个简短的脚本命令。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
其他回答
使用——从脚本中分离参数,并添加所有必需的参数,稍后我们可以通过索引访问它们。
npm run start -- myemail@gmail.com 100
你可以在节点中使用
const params = process.argv.slice(2);
console.log(params);
输出
['myemail@gmail.com', '100']
使用过程。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
的过程。[0]是可执行(节点)进程。Argv[1]是你的脚本。
在npm v5.3.0和node v8.4.0中测试
NPM 2和更新版本
从npm 2(2014)开始,可以将参数传递给npm。语法如下:
npm运行<命令> [-- <args>]
注意——separator,用来分隔传递给npm命令本身的参数和传递给脚本的参数。
在package.json的示例中:
"scripts": {
"grunt": "grunt",
"server": "node server.js"
}
下面是如何将参数传递给这些脚本:
npm run grunt -- task:target // invokes `grunt task:target`
npm run server -- --port=1337 // invokes `node server.js --port=1337`
注意:如果你的参数不是以-或——开头,那么显式的——分隔符是不需要的;但为了清晰起见,还是这样做比较好。
npm run grunt task:target // invokes `grunt task:target`
请注意下面的行为差异(test.js有console.log(process.argv)):以-或——开头的参数被传递给npm而不是脚本,并在那里被无声地吞下。
$ npm run test foobar
['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js', 'foobar']
$ npm run test -foobar
['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js']
$ npm run test --foobar
['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js']
$ npm run test -- foobar
['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js', 'foobar']
$ npm run test -- -foobar
['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js', '-foobar']
$ npm run test -- --foobar
['C:\\Program Files\\nodejs\\node.exe', 'C:\\git\\myrepo\\test.js', '--foobar']
当你使用npm实际使用的参数时,区别就更明显了:
$ npm test --help // this is disguised `npm --help test`
npm test [-- <args>]
aliases: tst, t
要获取参数值,请参见下面的问题。对于读取命名参数,最好使用yargs或minimist这样的解析库;Nodejs公开进程。argv,包含命令行参数值,但这是一个低级API(由空格分隔的字符串数组,由操作系统提供给节点可执行文件)。
注意:这种方法修改您的包。Json,如果你没有其他选择,使用它。
我必须将命令行参数传递给我的脚本,类似于:
"scripts": {
"start": "npm run build && npm run watch",
"watch": "concurrently \"npm run watch-ts\" \"npm run watch-node\"",
...
}
这意味着我用npm run start启动我的应用。
现在如果我想传递一些参数,我会从也许开始:
npm run start -- --config=someConfig
它的作用是:npm运行build && npm运行watch -- --config=someConfig。这样做的问题是,它总是将参数附加到脚本的末尾。这意味着所有链接脚本都不会得到这些参数(Args可能被所有脚本都需要,也可能不需要,但这是另一回事。)此外,当链接的脚本被调用时,这些脚本将不会得到传递的参数。例如,监视脚本不会得到传递的参数。
我的应用程序的生产使用是一个.exe,所以在exe中传递参数很好,但如果想在开发过程中这样做,就会出现问题。
我找不到任何合适的方法来实现这一点,所以这就是我尝试过的。
I have created a javascript file: start-script.js at the parent level of the application, I have a "default.package.json" and instead of maintaining "package.json", I maintain "default.package.json". The purpose of start-script.json is to read default.package.json, extract the scripts and look for npm run scriptname then append the passed arguments to these scripts. After this, it will create a new package.json and copy the data from default.package.json with modified scripts and then call npm run start.
const fs = require('fs');
const { spawn } = require('child_process');
// open default.package.json
const defaultPackage = fs.readFileSync('./default.package.json');
try {
const packageOb = JSON.parse(defaultPackage);
// loop over the scripts present in this object, edit them with flags
if ('scripts' in packageOb && process.argv.length > 2) {
const passedFlags = ` -- ${process.argv.slice(2).join(' ')}`;
// assuming the script names have words, : or -, modify the regex if required.
const regexPattern = /(npm run [\w:-]*)/g;
const scriptsWithFlags = Object.entries(packageOb.scripts).reduce((acc, [key, value]) => {
const patternMatches = value.match(regexPattern);
// loop over all the matched strings and attach the desired flags.
if (patternMatches) {
for (let eachMatchedPattern of patternMatches) {
const startIndex = value.indexOf(eachMatchedPattern);
const endIndex = startIndex + eachMatchedPattern.length;
// save the string which doen't fall in this matched pattern range.
value = value.slice(0, startIndex) + eachMatchedPattern + passedFlags + value.slice(endIndex);
}
}
acc[key] = value;
return acc;
}, {});
packageOb.scripts = scriptsWithFlags;
}
const modifiedJSON = JSON.stringify(packageOb, null, 4);
fs.writeFileSync('./package.json', modifiedJSON);
// now run your npm start script
let cmd = 'npm';
// check if this works in your OS
if (process.platform === 'win32') {
cmd = 'npm.cmd'; // https://github.com/nodejs/node/issues/3675
}
spawn(cmd, ['run', 'start'], { stdio: 'inherit' });
} catch(e) {
console.log('Error while parsing default.package.json', e);
}
现在,不是执行npm run start,而是执行node start-script.js——c=somethis——r=somethingElse
最初的运行看起来很好,但还没有彻底测试。如果你喜欢应用开发,可以使用它。
我发现这个问题,当我试图解决我的问题运行sequelize seed:generate cli命令:
node_modules/.bin/sequelize seed:generate --name=user
让我言归正传。我想在我的包中有一个简短的脚本命令。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