简体   繁体   English

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

[英]Read from config file in scripts section in package.json

Is there a possibility to read from a config file within the "scripts" section in package.json?是否有可能从 package.json 的"scripts"部分中的配置文件中读取?

Background of the question: We are several developers who all work on the same terminal server.问题背景:我们是几个开发人员,他们都在同一个终端服务器上工作。 And we have a the following section in our package.json我们的 package.json 中有以下部分

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

Since we are on the same server we need a way to specify a different port.由于我们在同一台服务器上,我们需要一种方法来指定不同的端口。 One possibility is to use a command line parameter.一种可能性是使用命令行参数。 But i would appreciate an "easier" way where i can store a port in a config file which i add to .gitignore , so that every developer can have his own file and we can just type npm run serve without thinking about to enter a port.但我希望有一种“更简单”的方式,我可以将端口存储在我添加到.gitignore的配置文件中,这样每个开发人员都可以拥有自己的文件,我们只需键入npm run serve而无需考虑输入端口.

Maybe there is a better way of doing what i want.也许有更好的方法来做我想做的事。 I am open to suggestions.我愿意接受建议。

One possibility is to use a command line parameter.一种可能性是使用命令行参数。

Yes, for that you'll need to configure your serve script in package.json like this:是的,为此你需要像这样在package.json 中配置你的serve脚本:

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

Then via you CLI tool run:然后通过您的 CLI 工具运行:

npm run serve -- <port_number>

Note: the <port_number> argument should replaced with a real port number, eg 8080 , 3000 etc ...注意: <port_number>参数应替换为实际端口号,例如80803000等...


...I would appreciate an "easier" way where I can store a port in a config file ... ...我希望能以一种“更简单”的方式将端口存储在配置文件中...

The config file:配置文件:

Let's say we have a file arbitrarily named .portnumber which is saved in the root of the project directory.假设我们有一个任意命名为.portnumber的文件,它保存在项目目录的根目录中。 For example:例如:

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

and the contents of the .portnumber file contains the port number to be used only. .portnumber文件的内容.portnumber包含要使用的端口号。 For example:例如:

3000

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

When running npm scripts on *nix platforms the default shell that npm utilizes is sh .*nix平台上运行 npm 脚本时,npm 使用的默认 shell 是sh Therefore the following will work.因此,以下将起作用。

package.json包.json

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

The $(<.portnumber) part above essentially reads the contents of the .portnumber file, (that's what the <.portnumber part does), and utilizes command Substitution .上面的$(<.portnumber)部分本质上读取.portnumber文件的内容,(这就是<.portnumber部分所做的),并利用命令 Substitution

So given that the .portnumber file contains 3000 the command being executed in the npm script is effectively:因此,鉴于.portnumber文件包含3000 ,在 npm 脚本中执行的命令是有效的:

vue-cli-service serve --port 3000

You could also do this:你也可以这样做:

package.json包.json

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

This is very similar to the previous, however if the .portnumber file did not exist or was empty, it would default to using 8080 for the port number.这与之前的非常相似,但是如果.portnumber文件不存在或为空,则默认使用8080作为端口号。


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

For a cross platform solution, (ie one that runs successfully on Windows, Linux, and macOS...), you'll need to utilize nodejs to achieve your requirement.对于跨平台解决方案(即在 Windows、Linux 和 macOS 上成功运行的解决方案...),您需要利用 nodejs 来实现您的要求。 There are a couple of different ways to approach this as described in the following two sub-sections titled:如以下两个小节所述,有几种不同的方法可以解决这个问题:

  • Using an external nodejs (.js) file使用外部 nodejs (.js) 文件
  • Inlining your JavaScript in package.json .package.json 中内联你的 JavaScript。

Using an external nodejs (.js) file使用外部 nodejs (.js) 文件

Create a file named serve.js创建一个名为serve.js的文件

serve.js服务.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'})

.. and also save it in your project directory: .. 并将其保存在您的项目目录中:

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

Redefine your serve npm script as follows:重新定义你的serve npm 脚本如下:

package.json包.json

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

Explanation:解释:

The serve.js file essentially does the following: serve.js文件主要执行以下操作:

  • Utilizes the node.js built-in readFileSync to read the contents of the .portnumber file and assigns the number to the port variable.利用 node.js 内置的readFileSync读取.portnumber文件的内容并将数字分配给port变量。

  • Then utilizes the node.js built-in execSync to run the vue-cli-service serve --port command with the port number that was previously read from the .portnumber file.然后利用 node.js 内置的execSync使用之前从.portnumber文件中读取的端口号运行vue-cli-service serve --port命令。

Inlining your JavaScript in package.json.在 package.json 中内联您的 JavaScript。

Alternatively, you can inline your nodejs/JavaScript code in the scripts section of your package.json instead.或者,您可以在 package.json 的脚本部分内联您的 nodejs/JavaScript 代码。 In which case redefine your npm script as follows:在这种情况下,重新定义您的 npm 脚本如下:

package.json包.json

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

Explanation:解释:

  • This is effectively the same, (albeit refactored), as the aforementioned solution that utilized a separate .js file, however the use of a separate nodejs script/file is now redundant.这实际上与前面提到的使用单独.js文件的解决方案相同(尽管进行了重构),但是现在使用单独的 nodejs 脚本/文件是多余的。
  • The nodejs command line option -e is utilized to evaluate the inline JavaScript. nodejs 命令行选项-e用于评估内联 JavaScript。

You can do all kinds of things, because npm is just running the command in a subshell.你可以做各种各样的事情,因为 npm 只是在子 shell 中运行命令。

For example, in Bash (or similar), you can use a config file:例如,在 Bash(或类似)中,您可以使用配置文件:

$ cat config.env
PORT=8080

And then source the file before running the actual command:然后在运行实际命令之前获取文件:

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

Or, in Windows, you can use a batch file:或者,在 Windows 中,您可以使用批处理文件:

C>type config.cmd
set PORT=8080

And then run the batch file before running the actual command:然后在运行实际命令之前运行批处理文件:

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

Note the weird call and %^PORT% syntax, that's not a typo.请注意奇怪的call%^PORT%语法,这不是打字错误。 In Windows this is required to delay expansion of the variable.在 Windows 中,这是延迟变量扩展所必需的。

Or, to make it more portable, use a Python/Node.js/whatever script.或者,为了使其更便携,使用 Python/Node.js/whatever 脚本。

One solution would be to add a .npmrc file in the root directory of the project and specify a different port for each developers:一种解决方案是在项目的根目录中添加一个.npmrc文件,并为每个开发人员指定不同的端口:

port=8081

Then you can use this variable in your app ( process.env.npm_config_port ) or package.json :然后你可以在你的应用程序( process.env.npm_config_port )或package.json 中使用这个变量:

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

By following your idea, you could add .npmrc to .gitignore .按照您的想法,您可以将.npmrc添加到.gitignore

An even cleaner way in my opinion would be to add .npmrc directly in the home directory of each developers, with a specific configuration for the project.在我看来,更简洁的方法是将.npmrc直接添加到每个开发人员的主目录中,并为项目进行特定配置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM