Egg.js配置系统详解:灵活应对多环境部署挑战
你是否还在为Node.js应用的多环境配置而烦恼?开发环境、测试环境、生产环境的配置切换是否让你手忙脚乱?Egg.js的配置系统提供了一套完整的解决方案,让你轻松应对各种部署场景。读完本文,你将掌握Egg.js配置系统的核心概念、多环境配置策略、配置加载顺序以及高级配置技巧,让你的应用配置管理变得简单而高效。
配置系统概述
Egg.js的配置系统是其核心功能之一,通过app.config可以访问应用的所有配置。配置系统的设计目标是提供灵活、可扩展的配置管理方式,支持多环境配置、配置合并、配置校验等功能。
Egg.js的配置文件主要存放在config目录下,包括:
- config/config.default.js:默认配置文件,所有环境都会加载
- config/config.local.js:本地开发环境配置
- config/config.unittest.js:测试环境配置
- config/plugin.js:插件配置
配置加载与合并规则
Egg.js的配置加载有严格的顺序,后加载的配置会覆盖先加载的配置。具体加载顺序如下:
- 框架默认配置
- 插件配置
- 应用默认配置(config/config.default.js)
- 环境特定配置(如config/config.local.js)
- 命令行参数
配置合并采用深度合并策略,对于对象类型的配置会进行递归合并,而非简单覆盖。例如:
// config.default.js
exports.logger = {
level: 'INFO',
consoleLevel: 'INFO'
};
// config.local.js
exports.logger = {
consoleLevel: 'DEBUG'
};
// 合并后的配置
{
logger: {
level: 'INFO',
consoleLevel: 'DEBUG'
}
}
多环境配置策略
Egg.js通过环境变量NODE_ENV来区分不同的运行环境,支持以下几种环境:
local:本地开发环境unittest:测试环境prod:生产环境- 自定义环境:如
pre(预发布环境)、test(测试环境)等
环境配置文件
针对不同环境,我们可以创建对应的配置文件:
- config/config.default.js:默认配置,所有环境都会加载
- config/config.local.js:本地开发环境,仅在
local环境加载 - config/config.unittest.js:测试环境,仅在
unittest环境加载 - config/config.prod.js:生产环境,仅在
prod环境加载
例如,本地开发环境可能需要开启DEBUG日志:
// config/config.local.js
exports.logger = {
coreLogger: {
consoleLevel: 'WARN',
},
};
而测试环境可能需要关闭日志缓冲:
// config/config.unittest.js
module.exports = {
logger: {
consoleLevel: 'WARN',
buffer: false,
},
};
环境判断
在代码中,可以通过app.config.env或appInfo.env来判断当前环境:
// app/service/user.js
async getUserInfo() {
if (this.app.config.env === 'local') {
// 本地环境特殊处理
return { id: 1, name: '本地测试用户' };
}
// 其他环境逻辑
return await this.app.mysql.get('user', { id: 1 });
}
核心配置详解
应用基本配置
config/config.default.js中定义了应用的基本配置:
module.exports = appInfo => {
return {
// 应用名称,取自package.json
name: appInfo.name,
// 密钥,用于cookie签名等安全功能
keys: '',
// 运行目录,用于存放临时文件
rundir: path.join(appInfo.baseDir, 'run'),
// 服务器监听配置
cluster: {
listen: {
port: 7001,
hostname: '',
},
},
};
};
其中appInfo是一个包含应用信息的对象,主要属性有:
appInfo.name:应用名称,取自package.jsonappInfo.baseDir:应用根目录appInfo.env:当前环境appInfo.root:应用根目录,等同于baseDir
服务器配置
Egg.js默认使用7001端口,可以在config/config.default.js中修改:
exports.cluster = {
listen: {
port: 8080, // 修改端口为8080
hostname: '0.0.0.0', // 允许外部访问
// path: '/var/run/egg.sock' // Unix socket路径,适用于生产环境
},
};
日志配置
日志配置是应用中非常重要的一部分,Egg.js提供了灵活的日志配置选项:
// config/config.default.js
exports.logger = {
dir: path.join(appInfo.root, 'logs', appInfo.name), // 日志目录
level: 'INFO', // 默认日志级别
consoleLevel: 'INFO', // 控制台日志级别
outputJSON: false, // 是否输出JSON格式日志
buffer: true, // 是否启用日志缓冲
};
在本地开发环境,我们通常会降低控制台日志级别以便调试:
// config/config.local.js
exports.logger = {
coreLogger: {
consoleLevel: 'WARN', // 核心日志控制台级别设为WARN
},
};
安全配置
Egg.js内置了多种安全机制,通过配置可以开启或关闭这些功能:
// config/config.default.js
exports.security = {
csrf: {
enable: true, // 开启CSRF保护
ignore: '/api/callback', // 忽略某些路径
},
xframe: {
enable: true, // 开启X-Frame-Options保护
},
};
中间件配置
Egg.js的中间件配置在config/config.default.js中进行:
// 内置中间件配置
exports.coreMiddleware = [
'meta',
'siteFile',
'notfound',
'bodyParser',
'overrideMethod',
];
// 自定义中间件配置
exports.middleware = [
'errorHandler',
'requestLog',
];
// 中间件参数配置
exports.errorHandler = {
match: '/api', // 只对/api路径生效
};
高级配置技巧
配置加密与敏感信息处理
对于密码、密钥等敏感信息,不应直接明文存储在配置文件中。Egg.js提供了配置加密功能:
// config/config.default.js
exports.crypto = {
secret: 'your-secret-key',
};
// 在代码中使用
const encrypted = this.app.crypto.encrypt('sensitive-data');
const decrypted = this.app.crypto.decrypt(encrypted);
同时,配置系统会自动忽略敏感字段,避免在日志中泄露:
// config/config.default.js
exports.dump = {
ignore: new Set([
'pass', 'pwd', 'password', 'keys',
/secret/i, // 忽略任何包含secret的字段
]),
};
配置动态更新
Egg.js支持运行时动态更新配置,通过app.configChanges事件可以监听配置变化:
// app.js
module.exports = app => {
app.on('configDidLoad', () => {
// 配置加载完成后执行
console.log('config loaded:', app.config);
});
app.on('configChanged', (data) => {
// 配置变化时执行
console.log('config changed:', data);
});
};
配置校验
为了确保配置的有效性,可以使用配置校验功能:
// config/config.default.js
exports.validate = {
// 配置校验规则
rules: {
'port': { type: 'number', required: true, min: 1, max: 65535 },
'logger.level': { type: 'enum', values: ['DEBUG', 'INFO', 'WARN', 'ERROR'] },
},
};
最佳实践
配置拆分
对于复杂应用,可以将配置按功能拆分到不同的文件中:
config/
├── config.default.js
├── config.local.js
├── config.prod.js
├── db.js // 数据库配置
├── cache.js // 缓存配置
└── thirdparty.js // 第三方服务配置
然后在主配置文件中引入:
// config/config.default.js
const db = require('./db');
const cache = require('./cache');
module.exports = appInfo => {
return {
...db(appInfo),
...cache(appInfo),
// 其他配置
};
};
环境变量注入
生产环境中,建议通过环境变量注入敏感配置:
// config/config.prod.js
module.exports = {
mysql: {
host: process.env.MYSQL_HOST || 'localhost',
port: process.env.MYSQL_PORT || 3306,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DATABASE,
},
};
配置文档化
建议在配置文件中添加详细注释,或维护单独的配置文档:
/**
* @member Config#redis
* @property {String} host - Redis服务器地址
* @property {Number} port - Redis服务器端口
* @property {String} password - Redis密码
* @property {Number} db - 数据库编号
*/
exports.redis = {
host: 'localhost',
port: 6379,
password: '',
db: 0,
};
总结
Egg.js的配置系统为应用提供了灵活而强大的配置管理能力,通过合理利用多环境配置、配置合并、敏感信息处理等功能,可以轻松应对各种复杂的部署场景。掌握Egg.js配置系统的核心概念和最佳实践,将有助于你构建更加健壮、可维护的Node.js应用。
更多配置相关的详细信息,请参考官方文档:
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考




