如何使用NPM配置变量跨平台(win / linux)?

时间:2017-02-10 18:50:31

标签: javascript node.js npm

使用npm_package_config_<variable>时,每个操作系统的使用情况不同。

package.json(Linux&amp; Windows)

config: {
    foo: "bar"
}

然后用于:

的Linux

node app.js --arg=$npm_package_config_foo

node app.js --arg=%npm_package_config_foo%

因此,我在scripts中创建了2个单独的package.json,但这感觉很麻烦。

任何获得这种跨平台的方式?

P.S。我了解cross-env插件,但这不适用于上述情况,仅适用于NODE_ENV。

更新

为了避免误解上下文,这是一个我正在寻找的真实案例场景,用于Docker命令指定端口号:

的package.json

"config": {
    "port": "3000"
}
...
"scripts": {
    "docker:build": "docker build --build-arg PORT=$npm_package_config_port -t my-app .",
    "docker:build:win": "docker build --build-arg PORT=%npm_package_config_port% -t my-app .",
}

3 个答案:

答案 0 :(得分:4)

您应该使用regex101.com

然后你可以简化为:

"scripts": { "docker:build": "cross-var docker build --build-arg PORT=$npm_package_config_port -t my-app .", }

答案 1 :(得分:2)

这实际上不需要跨平台,因为您没有使用环境变量。实际上,您只是尝试阅读传入的process.argv并确定需要在package.json中使用哪些配置变量。您可以使用像yargs这样的包,它会为您读取和解析process.argv,或者您可以自己解析process.argv并采取相应的行动。

以下是使用yargs作为问题中给出的示例的示例,此逻辑将进入my-app.js

const argv = require('yargs').argv;
const pkgJson = require('./package.json');

let config;

if (argv.arg) {
    let argSplit = argv.arg.split('_');
    let configVariable = argSplit[argSplit.length - 1];

    config = pkgJson.config[configVariable]
}

如果您需要使用环境变量,cross-env是可行的方法,您可以执行cross-env PORT=3000 node server之类的操作以传入端口等,这与您在问题中所说的不同,cross-env不仅限于NODE_ENV

编辑问题更新

通过执行

docker:builddocker:build:win的NPM脚本整合到一个脚本中

docker build --build-arg PORT=$(node -p process.env.npm_package_config_port) -t my-app .

以上将根据您的配置提取NPM为环境变量设置的值,然后将其返回。我没有使用docker所以我没有使用Docker进行测试,但是我使用echo进行了测试,并且值从$(node -p process.env.npm_package_config_port)返回。

更新2

看起来即使上面的命令在Windows上运行Powershell,NPM也会忽略运行命令的环境(GitBash,Cygwin,Powershell等)并生成自己的shell并使用{运行命令{1}}。简而言之,您将需要两个截然不同的构建命令,否则您将需要一些其他中间构建过程。

有关详细信息,请参阅GitHub上的NPM回购中的this issue

答案 2 :(得分:1)

简短回答:不能仅在exec()内实现跨平台,而不必像现在这样分成两个脚本。

长答案:如果单个脚本对&#39;繁琐的至关重要,那么请使用自定义节点脚本和"config": { "port": "3000", "name": "my-app" }, "scripts": { "docker:build": "node .scripts/docker.js" } 来自那里。

<强>的package.json

'use strict';

var exec = require('child_process').exec,
    port = process.env.npm_package_config_port || 3000,
    name = process.env.npm_package_config_name || 'my-app',
    cmd = 'docker build --build-arg PORT=' + port + ' -t ' + name + ' .';

exec(cmd, function(error, stdout, stderr) {
    if (error) {
        console.error(error);
        process.exit(1);
    }
});

<强> docker.js

CRLF