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

Read from config file in scripts section in package.json

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

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

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

由于我们在同一台服务器上,因此我们需要一种方法来指定不同的端口。一种可能性是使用命令行参数。但我希望有一种 "easier" 方式,我可以在配置文件中存储一个端口,然后添加到 .gitignore,这样每个开发人员都可以拥有自己的文件,我们只需键入 npm run serve不考虑入港

也许有更好的方法来做我想做的事。我乐于接受建议。

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

port=8081

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

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

按照您的想法,您可以将 .npmrc 添加到 .gitignore

在我看来,一种更简洁的方法是直接在每个开发人员的主目录中添加 .npmrc,并针对项目进行特定配置。

你可以做各种各样的事情,因为 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/whatever 脚本。

One possibility is to use a command line parameter.

是的,为此您需要在 package.json 中配置 serve 脚本,如下所示:

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

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

npm run serve -- <port_number>

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


...I would appreciate an "easier" way where I can store a port in a config file ...

配置文件:

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

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

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

3000

解决方案 A:*仅限 Nix 平台(Linux/MacOS...)

当 运行 在 *nix 平台上运行 npm 脚本时,npm 使用的默认 shell 是 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 文件主要执行以下操作:

  • 利用node.js内置的readFileSync读取.portnumber文件的内容,并将数字赋值给port变量。

  • 然后利用 node.js 内置的 execSync 到 运行 vue-cli-service serve --port 命令和先前从 .portnumber 文件.

在 package.json 中内联您的 JavaScript。

或者,您可以在 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 script/file 是多余的。
  • nodejs 命令行选项 -e 用于评估内联 JavaScript.