从package.json脚本部分的配置文件中读取

时间:2020-02-11 09:50:13

标签: node.js npm npm-scripts

是否可以从package.json的"scripts"节中的配置文件中读取?

问题的背景: 我们是几个开发人员,他们都在同一终端服务器上工作。我们的package.json

中有以下部分
...
"scripts": {
    "serve": "vue-cli-service serve --port 8080"
}
...

由于我们位于同一台服务器上,因此需要一种方法来指定其他端口。一种可能性是使用命令行参数。但是我希望以一种“简便”的方式将端口存储在添加到.gitignore的配置文件中,以便每个开发人员都可以拥有自己的文件,而我们只需键入npm run serve就可以了即将进入端口。

也许有一种更好的方式来做我想要的事情。我愿意接受建议。

3 个答案:

答案 0 :(得分:2)

您可以做各种事情,因为npm只是在子shell中运行命令。

例如,在Bash(或类似版本)中,您可以使用配置文件:

$ cat config.env
PORT=8080

然后在运行实际命令之前获取文件:

"scripts": {
    "serve": "source config.env && vue-cli-service serve --port $PORT"
}

或者,在Windows中,您可以使用批处理文件:

C>type config.cmd
set PORT=8080

然后在运行实际命令之前运行批处理文件:

"scripts": {
    "serve": "config.cmd && call vue-cli-service serve --port %^PORT%"
}

请注意,奇怪的call%^PORT%语法不是错字。在Windows中,这需要延迟变量的扩展。

或者,要使其具有更高的可移植性,请使用Python / Node.js /任何脚本。

答案 1 :(得分:2)

一种可能是使用命令行参数。

是的,为此,您需要像这样在 package.json 中配置serve脚本:

"scripts": {
  "serve": "vue-cli-service serve --port"
}

然后通过您的CLI工具运行:

npm run serve -- <port_number>

注意<port_number>参数应替换为真实的端口号,例如80803000等...


...我希望能以更轻松的方式将端口存储在配置文件中...

配置文件:

假设我们有一个任意命名为.portnumber的文件,该文件保存在项目目录的根目录中。例如:

.
├── .gitignore
├── .portnumber    <------ 
├── node_modules
│   └── ...
├── package.json
└── ...

.portnumber文件的内容包含仅可使用的端口号。例如:

3000

解决方案A: *仅适用于九个平台(Linux / MacOS ...)

* nix 平台上运行npm脚本时,npm使用的默认外壳为sh。因此,以下方法将起作用。

package.json

"scripts": {
  "serve": "vue-cli-service serve --port \"$(<.portnumber)\""
}

上面的$(<.portnumber)部分基本上读取了.portnumber文件的内容(这就是<.portnumber部分所做的事情),并利用了command Substitution

因此,假设.portnumber文件包含3000,则在npm脚本中执行的命令实际上是:

vue-cli-service serve --port 3000

您也可以这样做:

package.json

"scripts": {
  "serve-with-default": "port=$(<.portnumber); vue-cli-service serve --port \"${port:-8080}\""
}

这与前一个非常相似,但是如果.portnumber文件不存在或为空,则默认使用8080作为端口号。


解决方案B:跨平台(Windows / Linux / macOS ...)

对于跨平台解决方案(即在Windows,Linux和macOS上成功运行的解决方案...),您需要利用nodejs来满足您的要求。标题为以下两个小节的描述有两种不同的处理方法:

  • 使用外部nodejs(.js)文件
  • package.json 中内嵌JavaScript。

使用外部nodejs(.js)文件

创建一个名为serve.js的文件

serve.js

const readFileSync = require('fs').readFileSync;
const execSync = require('child_process').execSync;

const port = readFileSync('.portnumber', {encoding: 'utf8'});

execSync('vue-cli-service serve --port ' + port, {stdio: 'inherit'})

..并将其保存在您的项目目录中:

.
├── .gitignore
├── .portnumber    <------ 
├── node_modules
│   └── ...
├── package.json
├── serve.js       <------ 
└── ...

按以下方式重新定义您的serve npm脚本:

package.json

"scripts": {
  "serve": "node serve"
}

说明:

serve.js文件基本上执行以下操作:

  • 利用内置的readFileSync来读取.portnumber文件的内容,并将数字分配给port变量。

  • 然后利用内置的execSync来运行node.js,并使用先前从vue-cli-service serve --port文件中读取的端口号运行.portnumber命令。

将JavaScript内嵌在package.json中。

或者,您可以改为在package.json的脚本部分内联您的nodejs / JavaScript代码。在这种情况下,请重新定义您的npm脚本,如下所示:

package.json

"scripts": {
  "serve" : "node -e \"require('child_process').execSync('vue-cli-service serve --port ' + require('fs').readFileSync('.portnumber', {encoding: 'utf8'}), {stdio: 'inherit'})\""
}

说明:

  • 这实际上与前面提到的使用单独的.js文件的解决方案相同(尽管是重构的),但是现在使用单独的nodejs脚本/文件是多余的。
  • nodejs命令行选项-e用于评估嵌入式JavaScript。

答案 2 :(得分:1)

一种解决方案是在项目的根目录中添加一个 .npmrc 文件,并为每个开发人员指定一个不同的端口:

port=8081

然后,您可以在应用(process.env.npm_config_port)或 package.json 中使用此变量:

"scripts": {
    "serve": "vue-cli-service serve --port $npm_config_port"
}

按照您的想法,可以在 .gitignore 中添加 .npmrc

我认为,更干净的方法是将 .npmrc 直接添加到每个开发人员的主目录中,并为项目提供特定的配置。