如何存储Node.js部署设置/配置文件?

我一直在开发一些Node应用程序,并且我一直在寻找一种存储与部署相关设置的好模式。在Django世界(我来自的地方),常见的做法是有一个settings.py文件,其中包含标准设置(时区等),然后是一个local_settings.py用于部署特定设置,即。要与哪个数据库通信,哪个memache套接字,管理员的电子邮件地址等。

我一直在为Node寻找类似的模式。只是一个配置文件就好了,所以它不必与app.js中的其他所有内容一起卡住,但我发现有一种方法在不在源代码控制中的文件中具有特定于服务器的配置很重要。同一个应用程序很可能部署在具有截然不同设置的不同服务器上,并且必须处理合并冲突和所有这些都不是我的乐趣。

那么,有没有某种框架/工具可以做到这一点,或者每个人都只是自己动手做一些事情?

567096 次浏览

我使用package.json作为我的包,使用config.js作为我的配置,如下所示:

var config = {};


config.twitter = {};
config.redis = {};
config.web = {};


config.default_stuff =  ['red','green','blue','apple','yellow','orange','politics'];
config.twitter.user_name = process.env.TWITTER_USER || 'username';
config.twitter.password=  process.env.TWITTER_PASSWORD || 'password';
config.redis.uri = process.env.DUOSTACK_DB_REDIS;
config.redis.host = 'hostname';
config.redis.port = 6379;
config.web.port = process.env.WEB_PORT || 9980;


module.exports = config;

我从我的项目加载配置:

var config = require('./config');

然后我可以从config.db_hostconfig.db_port等访问我的东西……这让我可以使用硬编码参数,或者如果我不想在源代码控制中存储密码,则可以使用存储在环境变量中的参数。

我还生成了一个package.json并插入了一个依赖项部分:

"dependencies": {
"cradle": "0.5.5",
"jade": "0.10.4",
"redis": "0.5.11",
"socket.io": "0.6.16",
"twitter-node": "0.0.2",
"express": "2.2.0"
}

当我将项目克隆到我的本地机器时,我运行npm install来安装包。关于这里的更多信息。

该项目存储在GitHub中,并为我的正式服添加了遥控器。

很久以后,我发现了一个非常好的用于管理配置的Node.js模块:nconf

举个简单的例子:

var nconf = require('nconf');


// First consider commandline arguments and environment variables, respectively.
nconf.argv().env();


// Then load configuration from a designated file.
nconf.file({ file: 'config.json' });


// Provide default values for settings not provided above.
nconf.defaults({
'http': {
'port': 1337
}
});


// Once this is in place, you can just use nconf.get to get your settings.
// So this would configure `myApp` to listen on port 1337 if the port
// has not been overridden by any of the three configuration inputs
// mentioned above.
myApp.listen(nconf.get('http:port'));

它还支持在Redis中存储设置,编写配置文件,并具有相当可靠的API,并且还得到更受尊敬的Node.js商店之一Nodejitsu的支持,作为熨斗框架计划的一部分,因此它应该是相当面向未来的。

查看GitHub上的nconf

您还可以查看节点配置,它根据$主机$NODE_ENV变量(有点像RoR)加载配置文件:留档

这对于不同的部署设置(developmenttestproduction)非常有用。

我的解决方案相当简单:

将环境配置加载到./config/index.js

var env = process.env.NODE_ENV || 'development'
, cfg = require('./config.'+env);


module.exports = cfg;

在./config/config.global.js中定义一些默认值

var config = module.exports = {};


config.env = 'development';
config.hostname = 'dev.example.com';


//mongo database
config.mongo = {};
config.mongo.uri = process.env.MONGO_URI || 'localhost';
config.mongo.db = 'example_dev';

覆盖./config/config.test.js中的默认值

var config = require('./config.global');


config.env = 'test';
config.hostname = 'test.example';
config.mongo.db = 'example_test';


module.exports = config;

在./模型/user.js中使用它:

var mongoose = require('mongoose')
, cfg = require('../config')
, db = mongoose.createConnection(cfg.mongo.uri, cfg.mongo.db);

在测试环境中运行您的应用程序:

NODE_ENV=test node ./app.js

只需用exports做一个简单的settings.js

exports.my_password = 'value'

然后,在您的脚本中,执行require

var settings = require('./settings.js');

您的所有设置现在将通过settings变量可用:

settings.my_password // 'value'

您可以要求从Node v0.5. x(引用这个答案)开始的JSON文件

config.json:

{
"username" : "root",
"password" : "foot"
}

app.js:

var config = require('./config.json');
log_in(config.username, config.password);

除了这个答案中提到的nconf模块这个答案中提到的节点配置之外,还有节点信息解析器iniReader,它们似乎是更简单的. ini配置文件解析器。

定罪是另一个添加模式进行验证的选项。与nconf一样,它支持从环境变量、参数、文件和json对象的任意组合加载设置。

示例自述:

var convict = require('convict');
var conf = convict({
env: {
doc: "The applicaton environment.",
format: ["production", "development", "test"],
default: "development",
env: "NODE_ENV"
},
ip: {
doc: "The IP address to bind.",
format: "ipaddress",
default: "127.0.0.1",
env: "IP_ADDRESS",
},
port: {
doc: "The port to bind.",
format: "port",
default: 0,
env: "PORT"
}
});

入门文章: 使用节点定罪驯服配置

我在游戏中有点晚了,但我在这里或其他任何地方都找不到我需要的东西,所以我自己写了一些东西。

我对配置机制的要求如下:

  1. 支持前端,如果前端不能使用配置,那还有什么意义?
  2. 支持settings-overrides.js-看起来一样,但允许覆盖settings.js的配置。这里的想法是在不更改代码的情况下轻松修改配置。我发现它对saas很有用。

即使我不太关心支持环境-这将解释如何轻松地将其添加到我的解决方案中

var publicConfiguration = {
"title" : "Hello World"
"demoAuthToken" : undefined,
"demoUserId" : undefined,
"errorEmail" : null // if null we will not send emails on errors.


};


var privateConfiguration = {
"port":9040,
"adminAuthToken":undefined,
"adminUserId":undefined
}


var meConf = null;
try{
meConf = require("../conf/dev/meConf");
}catch( e ) { console.log("meConf does not exist. ignoring.. ")}








var publicConfigurationInitialized = false;
var privateConfigurationInitialized = false;


function getPublicConfiguration(){
if (!publicConfigurationInitialized) {
publicConfigurationInitialized = true;
if (meConf != null) {
for (var i in publicConfiguration) {
if (meConf.hasOwnProperty(i)) {
publicConfiguration[i] = meConf[i];
}
}
}
}
return publicConfiguration;
}




function getPrivateConfiguration(){
if ( !privateConfigurationInitialized ) {
privateConfigurationInitialized = true;


var pubConf = getPublicConfiguration();


if ( pubConf != null ){
for ( var j in pubConf ){
privateConfiguration[j] = pubConf[j];
}
}
if ( meConf != null ){
for ( var i in meConf ){
privateConfiguration[i] = meConf[i];
}
}
}
return privateConfiguration;


}




exports.sendPublicConfiguration = function( req, res ){
var name = req.param("name") || "conf";


res.send( "window." + name + " = " + JSON.stringify(getPublicConfiguration()) + ";");
};




var prConf = getPrivateConfiguration();
if ( prConf != null ){
for ( var i in prConf ){
if ( prConf[i] === undefined ){


throw new Error("undefined configuration [" + i + "]");
}
exports[i] = prConf[i];
}
}




return exports;

补充说明

  • undefined表示此属性是必需的
  • null表示它是可选的
  • meConf-目前代码的目标是app下的文件。meConf是覆盖目标是conf/dev的文件-我的vcs忽略了它。
  • publicConfiguration-将从前端和后端可见。
  • privateConfiguration-仅从后端可见。
  • sendPublicConfiguration-一个公开公共配置并将其分配给全局变量的路由。例如,下面的代码将在前端公开公共配置为全局变量myConf。默认情况下,它将使用全局变量名称conf

    app.get("/backend/conf","conf");

覆盖逻辑

  • Private ateConfiguration先与public Configuration合并,然后与meConf合并。
  • PublicConfiguration检查每个键是否有覆盖,并使用该覆盖。这样我们就不会暴露任何私有的东西。

添加环境支持

即使我不觉得“环境支持”有用,也许有人会。

要添加环境支持,您需要将meConf需要语句更改为类似于以下内容(伪代码)

如果(环境=="生产"){ //dev/meConf="…/conf/dev/meConf",//conf/dev/meConf//… }

如果(环境=="开发"){ meConf=要求("…/conf/dev/meConf")。开发; }

同样,您可以在每个环境中拥有一个文件

 meConf.development.js
meConf.production.js

并导入正确的。 其余的逻辑保持不变。

你们使用npm来启动脚本(env等)吗?

如果您使用.env文件,您可以将它们包含在您的package.json中 并使用npm来获取/启动它们。

示例:

{
"name": "server",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node test.js",
"start-dev": "source dev.env; node test.js",
"start-prod": "source prod.env; node test.js"
},
"dependencies": {
"mysql": "*"
}
}

然后运行npm脚本:

$ npm start-dev

这里描述了https://gist.github.com/ericelliott/4152984 艾瑞克·艾略特

您可以将康菲用于特定于环境的配置文件。它会自动加载json或yaml配置文件,它具有默认值和动态配置功能。

来自Konfig repo的示例:

File: config/app.json
----------------------------
{
"default": {
"port": 3000,
"cache_assets": true,
"secret_key": "7EHDWHD9W9UW9FBFB949394BWYFG8WE78F"
},


"development": {
"cache_assets": false
},


"test": {
"port": 3001
},


"staging": {
"port": #{process.env.PORT},
"secret_key": "3F8RRJR30UHERGUH8UERHGIUERHG3987GH8"
},


"production": {
"port": #{process.env.PORT},
"secret_key": "3F8RRJR30UHERGUH8UERHGIUERHG3987GH8"
}
}

开发中:

> config.app.port
3000

在生产中,假设我们从$ NODE_ENV=production PORT=4567 node app.js开始应用程序

> config.app.port
4567

更多详情:https://github.com/vngrs/konfig

我最近发布了一个小模块来加载任何类型的配置文件。 它非常简单,您可以在https://github.com/flesler/config-node

上查看它

您还可以查看dotenv,它遵循十二因子应用的原则。

我曾经使用node-config,但出于这个原因创建了dotenv。它完全受到ruby的dotenv库的启发。

用法很简单:

var dotenv = require('dotenv');
dotenv.load();

然后您只需创建一个. env文件并将您的设置放入其中,如下所示:

S3_BUCKET=YOURS3BUCKET
SECRET_KEY=YOURSECRETKEYGOESHERE
OTHER_SECRET_STUFF=my_cats_middle_name

这是nodejs的dotenv

对于那些正在访问这个旧线程的人来说,这里有一个我觉得很好的包。

我刚刚使用的一个alt示例是这样的,因为我想要比典型的. json文件更灵活,但不希望它抽象成需要依赖项的库。基本上,导出一个立即调用的函数,该函数返回一个带有我想要设置的值的对象。提供了很大的灵活性。

     module.exports = function(){
switch(node_env){
case 'dev':
return
{ var1 = 'development'};
}
}();

这里有一个更好的解释和完整的例子。在Node.js中使用配置文件

我知道这是一个非常古老的帖子。但我想分享我的配置环境变量的模块,我认为这是一个非常灵活的解决方案。 下面是模块json配置器

var configJson = {
'baseUrl': 'http://test.com',
'$prod_baseUrl': 'https://prod.com',
'endpoints': {
'users': '<%= baseUrl %>/users',
'accounts': '<%= baseUrl %>/accounts'
},
foo: 'bar',
foobar: 'foobar',
$prod_foo: 'foo in prod',
$test_foo: 'foo in test',
deep:{
veryDeep: {
publicKey: 'abc',
secret: 'secret',
$prod_secret: 'super secret'
}
}
};


var config = require('json-configurator')(configJson, 'prod');


console.log(config.deep.veryDeep.secret)
// super secret


console.log(config.endpoints.users)
// https://prod.com/users

然后,您可以使用process.env.NODE_ENV来获取环境的所有变量。

您可以使用pconf:https://www.npmjs.com/package/pconf

示例:

var Config = require("pconf");
var testConfig = new Config("testConfig");
testConfig.onload = function(){


testConfig.setValue("test", 1);
testConfig.getValue("test");
//testConfig.saveConfig(); Not needed


}

我要把我的帽子扔到这里,因为这些答案都没有解决几乎任何系统都需要的所有关键组件。注意事项:

  • 公共配置(可以被前端看到)和私有配置(盖伊·莫格拉比说得对)。并确保它们是分开的。
  • 像钥匙一样的秘密
  • 默认与特定于环境的覆盖
  • 前端包

以下是我的配置方式:

  • config.default.private.js-在版本控制中,这些是只能由后端看到的默认配置选项。
  • config.default.public.js-在版本控制中,这些是后端可以看到的默认配置选项前端
  • config.dev.private.js-如果您需要不同的开发私有默认值。
  • config.dev.public.js-如果您需要不同的开发公共默认值。
  • config.private.js-不在版本控制中,这些是覆盖config.default.private.js的环境特定选项
  • config.public.js-不在版本控制中,这些是覆盖config.default.public.js的环境特定选项
  • keys/-每个文件存储某种不同秘密的文件夹。这也不受版本控制(密钥永远不应该受版本控制)。

我使用普通的javascript文件进行配置,所以我拥有javascript语言的全部功能(包括注释和在环境特定文件中加载默认配置文件的能力,这样它们就可以被覆盖)。如果你想使用环境变量,你可以在这些配置文件中加载它们(尽管我建议不要使用env vars,因为同样的原因我不建议使用json文件——你没有编程语言的能力来构造你的配置)。

每个密钥都在一个单独的文件中的原因是供安装程序使用。这允许您有一个安装程序在机器上创建密钥并将它们存储在密钥文件夹中。如果没有这个,当您加载无法访问密钥的配置文件时,您的安装程序可能会失败。这样您就可以遍历目录并加载该文件夹中的任何密钥文件,而不必担心在任何给定版本的代码中存在什么,不存在什么。

由于您可能在私有配置中加载了密钥,因此绝对不想在任何前端代码中加载私有配置。虽然将前端代码库与后端完全分开可能更理想,但很多时候PITA是一个足够大的障碍,阻止人们这样做,因此私有配置与公共配置。但是我做了两件事来防止私有配置在前端加载:

  1. 我有一个单元测试,确保我的前端包不包含我在私有配置中拥有的密钥之一。
  2. 我的前端代码与后端代码位于不同的文件夹中,我有两个名为“config.js”的不同文件-每个文件都有一个。对于后端,config.js加载私有配置,对于前端,它加载公共配置。然后你总是需要('config'),而不用担心它来自哪里。

最后一件事:你的配置应该通过一个完全单独的文件加载到浏览器中,而不是其他前端代码。如果你捆绑了前端代码,公共配置应该构建为一个完全独立的捆绑包。否则,你的配置不再是真正的配置了——它只是你代码的一部分。配置需要能够在不同的机器上有所不同。

我在这里尝试了一些建议的解决方案,但没有使用它们,所以我创建了自己的模块。它被称为mikro-config,主要区别在于它尊重约定而不是配置,所以你可以只需要模块并开始使用它。

您将配置存储在/config文件夹中的普通js或json文件中。首先它加载default.js文件,然后从/config目录加载所有其他文件,然后它加载基于$NODE_ENV变量的环境特定配置。

它还允许使用local.js或特定于环境的/config/env/$NODE_ENV.local.js覆盖此配置以进行本地开发。

你可以在这里看看:

https://www.npmjs.com/package/mikro-config

https://github.com/B4nan/mikro-config

长期以来,我一直使用这里的解决方案中提到的方法。然而,对于明文中的机密的安全性存在担忧。您可以使用config之上的另一个包,以便处理安全位。

看看这个:https://www.attosol.com/secure-application-secrets-using-masterkey-in-azure-key-vault/

我将创建一个文件夹作为配置文件命名为config.js,以后我将在需要的地方使用此文件,如下所示

config.js示例

module.exports = {
proxyURL: 'http://url:port',
TWITTER: {
consumerkey: 'yourconsumerkey',
consumerSecrete: 'yourconsumersecrete'
},
GOOGLE: {
consumerkey: 'yourconsumerkey',
consumerSecrete: 'yourconsumersecrete'
},
FACEBOOK: {
consumerkey: 'yourconsumerkey',
consumerSecrete: 'yourconsumersecrete'
}
}

然后如果我想在某个地方使用这个配置文件

我将首先导入如下

var config = require('./config');

我可以得到如下的值

const oauth = OAuth({
consumer: {
key: config.TWITTER.consumerkey,
secret: config.TWITTER.consumerSecrete
},
signature_method: 'HMAC-SHA1',
hash_function(base_string, key) {
return crypto.createHmac('sha1', key).update(base_string).digest('base64');
}
});

最好将发展“制作”配置分开。

我使用以下方式: 这是我的配置/index.js文件:

const config = {
dev : {
ip_address : '0.0.0.0',
port : 8080,
mongo :{
url : "mongodb://localhost:27017/story_box_dev",
options : ""
}
},
prod : {
ip_address : '0.0.0.0',
port : 3000,
mongo :{
url : "mongodb://localhost:27017/story_box_prod",
options : ""
}
}
}

对于需要配置使用以下内容:

const config = require('../config')[process.env.NODE_ENV];

然后你可以使用config对象:

const ip_address = config.ip_address;
const port = config.port;

只需使用npm模块config(超过300000次下载)

https://www.npmjs.com/package/config

Node-config为您的应用部署组织分层配置。

它允许您定义一组默认参数,并将它们扩展到不同的部署环境(开发、qa、暂存、生产等)。

$ npm install config
$ mkdir config
$ vi config/default.json




{
// Customer module configs
"Customer": {
"dbConfig": {
"host": "localhost",
"port": 5984,
"dbName": "customers"
},
"credit": {
"initialLimit": 100,
// Set low for development
"initialDays": 1
}
}
}






$ vi config/production.json


{
"Customer": {
"dbConfig": {
"host": "prod-db-server"
},
"credit": {
"initialDays": 30
}
}
}






$ vi index.js


var config = require('config');
//...
var dbConfig = config.get('Customer.dbConfig');
db.connect(dbConfig, ...);


if (config.has('optionalFeature.detail')) {
var detail = config.get('optionalFeature.detail');
//...
}




$ export NODE_ENV=production
$ node index.js

这是一个受这篇文章启发的整洁方法。除了无处不在的软糖包之外,它不需要任何额外的包。此外,它允许您使用特定于环境的覆盖来管理嵌套默认值。

首先,在包根路径中创建一个配置文件夹,如下所示

package
|_config
|_ index.js
|_ defaults.json
|_ development.json
|_ test.json
|_ production.json

这是index.js档案

const _ = require("lodash");
const defaults = require("./defaults.json");
const envConf = require("./" + (process.env.NODE_ENV || "development") + ".json" );
module.exports = _.defaultsDeep(envConf, defaults);

现在假设我们有这样的defaults.json

{
"confKey1": "value1",
"confKey2": {
"confKey3": "value3",
"confKey4": "value4"
}
}

development.json这样

{
"confKey2": {
"confKey3": "value10",
}
}

如果你这样做config = require('./config')这里是你会得到什么

{
"confKey1": "value1",
"confKey2": {
"confKey3": "value10",
"confKey4": "value4"
}
}

请注意,除了在特定于环境的文件中定义的值之外,您可以获得所有默认值。因此,您可以管理配置层次结构。使用defaultsDeep可以确保您甚至可以拥有嵌套默认值。

npm i config


In config/default.json
{
"app": {
"port": 3000
},
"db": {
"port": 27017,
"name": "dev_db_name"
}
}


In config/production.json
{
"app": {
"port": 4000
},
"db": {
"port": 27000,
"name": "prod_db_name"
}
}


In index.js


const config = require('config');


let appPort = config.get('app.port');
console.log(`Application port: ${appPort}`);


let dbPort = config.get('db.port');
console.log(`Database port: ${dbPort}`);


let dbName = config.get('db.name');
console.log(`Database name: ${dbName}`);


console.log('NODE_ENV: ' + config.util.getEnv('NODE_ENV'));


$ node index.js
Application port: 3000
Database port: 27017
Database name: dev_db_name
NODE_ENV: development


For production
$ set NODE_ENV=production
$ node index.js
Application port: 4000
Database port: 27000
Database name: prod_db_name
NODE_ENV: production

我们如何用TypeScript做到这一点。

export const loadConfig = () => {
const configLoadeded = configLoader.util.toObject() as any
Config = configLoadeded
}


export interface ConfigI {
productName: string;
productId: string;
googleCloudApiKey: string;
}

有点晚了(只有10年),但我使用的config.js结构如下:

const env = process.env.NODE_ENV || 'development';


var config_temp = {
default:{
port: 3000,
mysql_host: "localhost",
logging_level: 5,
secret_api_key: process.env.SECRET_API_KEY
},
development: {
logging_level: 10
},
production: {
port: 3001,
mysql_host: "not-localhost"
}
};
var config = {
...config_temp.default,
...config_temp[env]
}
module.exports = config;

然后我加载配置:

var config = require('./config');
var port = config.port;

以这种方式:

  • env变量的读取包含在config.js文件中,因此我可以避免这种丑陋:require('./config')[process.env.NODE_ENV || 'development']
  • 文件config.js可以上传到代码的存储库中,因为敏感变量继续使用process.env处理。
  • 如果相同的元素同时包含在default:{custom_env:{中,则只保留第二个元素。
  • 没有专用文件夹和多个文件(如配置

如今,在使用数据库时,最简单的做法是根本不处理配置文件,因为部署环境更容易仅使用单个环境变量进行设置,例如,将其称为DB_CONNECTION,并根据需要传递任何其他配置数据。

配置数据示例:

const config = {
userIds: [1, 2, 3],
serviceLimit: 100,
// etc., configuration data of any complexity
};
// or you can read it from a config file

创建一个连接字符串,其中包含数据库驱动程序不关心的额外参数:

import {ConnectionString} from 'connection-string';


const cs = new ConnectionString('postgres://localhost@dbname', {
user: 'user-name',
password: 'my-password',
params: {
config
}  ​
});

然后我们可以生成结果字符串以将其存储在环境中:

cs.toString();
//=>postgres://localhost:my-password@dbname?config=%7B%22userIds%22%3A%5B1%2C2%2C3%5D%2C%22serviceLimit%22%3A100%7D

因此,您将其存储在您的环境中,例如DB_CONNECTION,并且在客户端进程中,您可以通过process.env.DB_CONNECTION读取它:

const cs = new ConnectionString(process.env.DB_CONNECTION);


const config = JSON.parse(cs.params?.config); // parse extra configuration
//=> { userIds: [ 1, 2, 3 ], serviceLimit: 100 }

这样,您将拥有连接和所需的所有额外配置,所有这些都在一个环境变量中,无需混淆配置文件。

我使用做十个v-Flow进行配置管理。

这是按预期工作的。通常情况下,您有多个 本地、开发、分期和生产等环境。只需流动这些 创建自己的环境。

1. npm i dotenv-flow。

2.创建类似.env | .env.dev | .env.prod的文件。

出于测试目的复制此内容

.env

DATABASE_HOST=global
DATABASE_PORT=global
DATABASE_USER=global
DATABASE_PASS=global
DATABASE_NAME=global

.env.dev

DATABASE_NAME=dev
DATABASE_PASS=dev

.env.prod

DATABASE_NAME=prod
DATABASE_PASS=prod

现在使用这些环境变量创建一个测试文件。

test.js

console.log('database host:', process.env.DATABASE_HOST);
console.log('database port:', process.env.DATABASE_PORT);
console.log('database user:', process.env.DATABASE_USER);
console.log('database pass:', process.env.DATABASE_PASS);
console.log('database name:', process.env.DATABASE_NAME);

现在使用这些命令来运行您的脚本。

node -r dotenv-flow/config test.js
node -r dotenv-flow/config test.js --node-env=dev
node -r dotenv-flow/config test.js --node-env=prod

如果您在特定文件夹中创建这些环境变量文件,例如我在envs文件夹中创建了这些文件,那么请使用以下命令。

node -r dotenv-flow/config test.js --dotenv-flow-path=./envs
node -r dotenv-flow/config test.js --dotenv-flow-path=./envs --node-env=dev
node -r dotenv-flow/config test.js --dotenv-flow-path=./envs --node-env=prod

试试properties-gen https://www.npmjs.com/package/properties-gen

node-config非常相似,它加载一个配置基文件并根据您设置的环境使用extfile对其进行扩展,但这是一个按需运行且完全可配置的cli。

npx properties-gen init

要创建cli配置,请将其安装在您的项目中

npm install properties-gen --save-dev

定义您的配置文件(基础和扩展)并在构建过程之前或在项目中启动开发服务器之前运行generate命令。

{
"name": "myApp",
"scripts": {
"config": "properties-gen generate",
"dev": "npm run config && next dev",
"build": "npm run config && next build",
"start": "next start"
}
}

一个很酷的事情是您可以定义多个配置组,以防您需要生成多个输出,例如客户端和服务器特定文件。