Javascript 将命令行参数发送到npm脚本
我的Javascript 将命令行参数发送到npm脚本,javascript,node.js,npm,Javascript,Node.js,Npm,我的包.json的脚本部分目前看起来如下: “脚本”:{ “开始”:“节点。/script.js服务器” } …这意味着我可以运行npm start来启动服务器。到目前为止还不错 但是,我希望能够运行类似于npmstart8080的程序,并将参数传递给script.js(例如npmstart8080=>节点。/script.js服务器8080)。这可能吗?npm 2及更新版本 自npm第二次会议(2014年)以来,这是可能的。语法如下: npm start --port:5000 npm运行
包.json的脚本部分目前看起来如下:
“脚本”:{
“开始”:“节点。/script.js服务器”
}
…这意味着我可以运行npm start
来启动服务器。到目前为止还不错
但是,我希望能够运行类似于npmstart8080
的程序,并将参数传递给script.js
(例如npmstart8080
=>节点。/script.js服务器8080
)。这可能吗?npm 2及更新版本
自npm第二次会议(2014年)以来,这是可能的。语法如下:
npm start --port:5000
npm运行[-]
注意--
分隔符,用于分隔传递给npm
命令本身的参数和传递给脚本的参数
使用示例package.json
:
"scripts": {
"grunt": "grunt",
"server": "node server.js"
}
"config": {
"myPort": "8080"
}
"scripts": {
"cool": "./cool.js"
}
以下是如何将参数传递给这些脚本:
npm运行grunt--task:target//调用'grunt task:target'`
npm运行服务器--port=1337//调用`node server.js--port=1337`
注意:如果参数不是以-
或-
开头,则不需要显式的-
分隔符;但为了清晰起见,最好还是这样做。
npm运行grunt任务:目标//调用`grunt任务:目标`
注意下面的行为差异(test.js
有console.log(process.argv)
):以-
或-
开头的参数被传递给npm
而不是脚本,并在那里被默默地吞没
$npm运行测试foobar
['C:\\ProgramFiles\\nodejs\\node.exe','C:\\git\\myrepo\\test.js','foobar']
$npm运行测试-foobar
['C:\\Program Files\\nodejs\\node.exe','C:\\git\\myrepo\\test.js']
$npm运行测试--foobar
['C:\\Program Files\\nodejs\\node.exe','C:\\git\\myrepo\\test.js']
$npm运行测试--foobar
['C:\\ProgramFiles\\nodejs\\node.exe','C:\\git\\myrepo\\test.js','foobar']
$npm运行测试--foobar
['C:\\Program Files\\nodejs\\node.exe','C:\\git\\myrepo\\test.js','-foobar']
$npm运行测试--foobar
['C:\\ProgramFiles\\nodejs\\node.exe','C:\\git\\myrepo\\test.js','-foobar']
当您使用npm实际使用的参数时,差异更为明显:
然后添加到package.json
:
"scripts": {
"grunt": "grunt",
"server": "node server.js"
}
"config": {
"myPort": "8080"
}
"scripts": {
"cool": "./cool.js"
}
在您的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
console.log({ myVar: process.env.npm_config_myVar });
console.log('arguments: ' + process.argv.slice(2));
这样,默认情况下,npm start
将使用8080。但是,您可以对其进行配置(该值将由npm
存储在其内部存储器中):
然后,当调用npm start
时,将使用9090(覆盖package.json
中的默认值)。据我所见,当人们希望以更简单的方式运行脚本时,会使用package.json脚本。例如,要使用安装在本地node_模块中的nodemon
,我们不能直接从cli调用nodemon
,但可以使用/node_modules/nodemon/nodemon.js
调用它。所以,为了简化长时间的输入,我们可以把这个
...
scripts: {
'start': 'nodemon app.js'
}
...
等等
在这一点上,使用符号链接是我能找到的最好的方法,但我并不认为这是最佳实践
我也希望你能对我的回答发表意见。你也可以这样做:
在package.json
中:
"scripts": {
"grunt": "grunt",
"server": "node server.js"
}
"config": {
"myPort": "8080"
}
"scripts": {
"cool": "./cool.js"
}
在cool.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
console.log({ myVar: process.env.npm_config_myVar });
console.log('arguments: ' + process.argv.slice(2));
在CLI中:
npm --myVar=something run-script cool
应输出:
{ myVar: 'something' }
更新:使用npm 3.10.3,它似乎将process.env.npm\u config\u
变量小写?我还使用了更好的npm运行
,所以我不确定这是否是普通的默认行为,但这个答案是有效的。与其使用process.env.npm\u config\u myVar
,不如尝试使用process.env.npm\u config\u myVar
这并不能真正回答您的问题,但您可以始终使用环境变量:
"scripts": {
"start": "PORT=3000 node server.js"
}
然后在server.js文件中:
var port = process.env.PORT || 3000;
您要求能够运行类似于npmstart8080
的程序。这是可能的,无需修改script.js
或以下配置文件
例如,在“脚本”
JSON值中,包括--
然后从命令行:
$ PORT=8080 npm start
我已经用bash和npm1.4.23证实了这一点。请注意,此解决方案不需要解决GitHub npm。从npm 2.x开始,您可以使用--
终端
npm运行脚本启动--foo=3
Package.json
"scripts: {
"seed:generate":"NODE_ENV=development node_modules/.bin/sequelize seed:generate"
}
“开始”:“node./index.js”
Index.js
console.log('process.argv',process.argv);
如果希望将参数传递到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
只运行一次常规构建。jakub.g的答案是正确的,但是使用grunt的示例似乎有点复杂
所以我简单的回答是:
-向npm脚本发送命令行参数
将命令行参数发送到npm脚本的语法:
npm run [command] [-- <args>]
"scripts": {
"start": "webpack-dev-server --port process.env.port || 8080"
},
我们使用npm start
现在,如果我们要将端口传递给npm脚本:
npm run [command] [-- <args>]
"scripts": {
"start": "webpack-dev-server --port process.env.port || 8080"
},
运行此命令并通过命令行传递端口,例如5000,如下所示:
npm start --port:5000
-使用package.json配置:
正如jakub.g所提到的,您也可以在package.json的配置中设置参数
"scripts": {
"start": "NODE_ENV=development node local.js"
}
npm start
将使用配置中指定的端口,或者您也可以覆盖它
npm config set myPackage:myPort 3000
-在npm脚本中设置参数
在npm脚本中读取变量集的示例。在本例中,NODE\u ENV
"scripts": {
"start:prod": "NODE_ENV=prod node server.js",
"start:dev": "NODE_ENV=dev node server.js"
},
在server.js prod或dev中读取节点_ENV
在代码中使用process.argv
,然后只提供一个尾随$
"script":{
"start" : "ng serve --port="
}
"script":{
"build" : "copy c:/file <arg> && ng build"
}
"scripts": {
"command": "sh -c 'someprogram --env=$0'"
}
"scripts": {
"start": "npm run build && npm run watch",
"watch": "concurrently \"npm run watch-ts\" \"npm run watch-node\"",
...
}
npm run start -- --config=someConfig
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);
}
{
"name": "argument",
"version": "1.0.0",
"scripts": {
"argument": "echo \"The value of --foo is '${npm_config_foo}'\""
}
}
npm run argument --foo=bar
npm start '{"PROJECT_NAME_STR":"my amazing stuff", "CRAZY_ARR":[0,7,"hungry"], "MAGICAL_NUMBER_INT": 42, "THING_BOO":true}';
"scripts": {
"start": "NODE_ENV=development node local.js"
}
console.log(process.env.NODE_ENV, starter_obj.CRAZY_ARR, starter_obj.PROJECT_NAME_STR, starter_obj.MAGICAL_NUMBER_INT, starter_obj.THING_BOO);
var starter_obj = JSON.parse(JSON.parse(process.env.npm_config_argv).remain[0]);
TEST_ENV_VAR=hello npm start
<my_script> value