包的脚本部分。Json当前看起来是这样的:

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

...这意味着我可以运行npm start来启动服务器。到目前为止一切顺利。

然而,我希望能够运行类似npm start 8080的东西,并将参数传递给script.js(例如npm start 8080 => node ./script.js服务器8080)。这可能吗?


当前回答

当我需要部署到不同的环境时,我也遇到了同样的问题 这是包裹。Json预发布更新。

 scripts:
{"deploy-sit": "sls deploy --config resources-sit.yml",
 "deploy-uat": "sls deploy --config resources-uat.yml",
 "deploy-dev": "sls deploy --config resources-dev.yml"}

但这里是采用环境变量而不是重复自己的正确方法

scripts:{"deploy-env": "sls deploy --config resources-$ENV_VAR.yml"}

最后,您可以通过运行进行部署 ENV_VAR=dev npm运行deploy-env

其他回答

你也可以这样做:

在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

在我看来,人们使用包装。Json脚本,当他们想以更简单的方式运行脚本。例如,要使用安装在本地node_modules中的nodemon,我们不能直接从cli调用nodemon,但可以通过./node_modules/nodemon/nodemon.js调用它。所以,为了简化这种冗长的输入,我们可以把这个…


    ...

    scripts: {
      'start': 'nodemon app.js'
    }

    ...

... 然后调用NPM start使用“nodemon”,它的第一个参数是app.js。

我想说的是,如果你只是想用node命令启动你的服务器,我认为你不需要使用脚本。输入npm start或node app.js也有同样的效果。

但如果你确实想使用nodemon,并且想传递一个动态参数,也不要使用script。尝试使用符号链接代替。

例如使用sequelize迁移。我创建了一个符号链接…

Ln -s node_modules/sequelize/bin/sequelize

... 当我调用它时,我可以传递任何参数…

./sequlize -h /* show help */

./sequelize -m /* upgrade migration */

./sequelize -m -u /* downgrade migration */

等等……

在这一点上,使用符号链接是我能想出的最好的方法,但我真的不认为这是最好的实践。

我也希望你能对我的回答提出意见。

注意:这种方法修改您的包。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

最初的运行看起来很好,但还没有彻底测试。如果你喜欢应用开发,可以使用它。

适用于Windows系统下的PowerShell用户

接受的答案不为我的npm 6.14工作。无论是添加“不”还是包含“一次”都不起作用。但是,在实参前面放两次——或者放一次“——”就可以了。例子:

npm run <my_script> -- -- <my arguments like --this>

怀疑的理由

像在bash中一样,——指示PowerShell将以下所有参数视为字面字符串,而不是选项(例如,请看这个答案)。问题似乎是该命令比预期的多解释了一次,丢失了“——”。例如,通过做

npm run <my_script> -- --option value

NPM将运行

<my_script> value

然而,做

npm run <my_script> "--" --option value

结果

<my_script> "--option" "value"

这很好。

我满足于这样的东西,看看测试观察脚本:

"scripts": {
    "dev": "tsc-watch --onSuccess \"node ./dist/server.js\"",
    "test": "tsc && cross-env NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest",
    "test-watch": "cross-env NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 tsc-watch --onSuccess",
  },

你像这样调用test-watch脚本:

// Run all tests with odata in their name
npm run test-watch "jest odata"