wzc-nest-nacos-config
v0.1.7
Published
|日期|人员|版本| | ---- | ---- | ---- | |2025-07-23|吴占超|v1.0.0|
Readme
nest-nacos-config
|日期|人员|版本| | ---- | ---- | ---- | |2025-07-23|吴占超|v1.0.0|
A NestJS module for loading configuration from Nacos.
package
依赖 nest-typed-config 进行 本地 config 读取。
v2.6.0 搭配 nacos v2
安装使用
- env.development.yaml
path: conf/env.development.yaml
nodeEnv: local
nacos:
server: 127.0.0.1:8848
namespace: d211f656-d9be-4806-80fd-8b77965dedcc
configRequestTimeout: 6000
account: nacos
password: nacos
configId: dev-bpm-config
group: DEFAULT_GROUP
# install package
$ yarn add wzc-nest-nacos-configapp.module.ts
NacosConfigModule.forRootAsync 配置env 读取 nacos 配置
import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { NacosConfigModule } from 'wzc-nest-nacos-config';
import { AppConfigSchema } from './config/app.config.schema';
import { RequestIdMiddleware } from './middleware/request-id.middleware';
import { LoggerModule } from './log/logger.module';
import { DatabaseModule } from './database/database.module';
@Module({
imports: [
NacosConfigModule.forRootAsync({
useFactory: () => ({
schema: AppConfigSchema,
/**
* basename: 'env', // 基础名称为 .env (匹配文件开头)
// searchPlaces: [
// '.env.development.yaml', // 直接指定要加载的配置文件
// ],
searchFrom: 'conf', // 指定搜索路径为 conf 目录 (非常重要)
*/
fileLoadOptions: {
basename: `env.${process.env.NODE_ENV || 'development'}`,
searchFrom: 'conf',
},
onChange: () => {
console.log('配置变了');
},
}),
}),
LoggerModule,
DatabaseModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(RequestIdMiddleware).forRoutes('*');
}
}logger.module.ts
const newConfig = await EmitterUtils.subscribeLoadConfigEnd(); 异步等待config 加载完成。
import * as chalk from 'chalk'; // 用于颜色化输出
import { WinstonModule } from 'nest-winston';
import { createLogger, format, transports } from 'winston';
import * as DailyRotateFile from 'winston-daily-rotate-file';
import { get } from 'lodash';
import { EmitterUtils } from 'wzc-nest-nacos-config';
import { RequestContext } from 'src/context/request-context';
// 定义日志级别颜色
const levelsColors = {
error: chalk.red,
warn: chalk.yellow,
info: chalk.green,
debug: chalk.blue,
verbose: chalk.cyan,
};
export const LoggerModule = WinstonModule.forRootAsync({
useFactory: async () => {
const newConfig = await EmitterUtils.subscribeLoadConfigEnd();
const winstonLoggerConfig = newConfig?.nacosConfig?.winstonLoggerConfig;
return createLogger({
format: format.combine(
format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), // 添加时间戳
format.errors({ stack: true }), // 捕获错误堆栈信息
format.splat(), // 处理占位符
format.json(), // JSON 格式日志
format.prettyPrint(), // 美化打印
),
defaultMeta: {
service: 'log-service',
requestId: RequestContext.get('requestId'), // 例如使用 AsyncLocalStorage 获取
},
transports: [
new DailyRotateFile({
filename: `${winstonLoggerConfig?.filename || 'logs'}/errors/error-%DATE%.log`,
datePattern: winstonLoggerConfig?.datePattern || 'YYYY-MM-DD',
zippedArchive:
winstonLoggerConfig?.zippedArchive !== undefined
? winstonLoggerConfig?.zippedArchive
: true,
maxSize: winstonLoggerConfig?.maxSize || '100m',
maxFiles: winstonLoggerConfig?.maxFiles || '15d',
level: 'error',
}),
new DailyRotateFile({
filename: `${winstonLoggerConfig?.filename || 'logs'}/warnings/warning-%DATE%.log`,
datePattern: winstonLoggerConfig?.datePattern || 'YYYY-MM-DD',
zippedArchive:
winstonLoggerConfig?.zippedArchive !== undefined
? winstonLoggerConfig?.zippedArchive
: true,
maxSize: winstonLoggerConfig?.maxSize || '100m',
maxFiles: winstonLoggerConfig?.maxFiles || '15d',
level: 'warn',
}),
new DailyRotateFile({
filename: `${winstonLoggerConfig?.filename || 'logs'}/app/app-%DATE%.log`,
datePattern: winstonLoggerConfig?.datePattern || 'YYYY-MM-DD',
zippedArchive:
winstonLoggerConfig?.zippedArchive !== undefined
? winstonLoggerConfig?.zippedArchive
: true,
maxSize: winstonLoggerConfig?.maxSize || '100m',
maxFiles: winstonLoggerConfig?.maxFiles || '15d',
}),
new transports.Console({
format: format.combine(
format.colorize({ all: true }), // 自动为日志级别和信息着色
format.printf(({ level, message, timestamp, stack }) => {
const color = get(levelsColors, level, chalk.white);
return color(`[${timestamp}] [${level}] ${stack || message}`);
}),
),
level: 'debug',
}),
],
});
},
});
