点击上方 程序员成长指北,关注公众号
回复1,加入高级Node交流群
来源 | https://trilon.io/blog/announcing-nestjs-11-whats-new编译 | 公众号 Nodejs技术栈
很高兴地正式宣布 NestJS 11 发布!这个版本包含了大量的 bug 修复、增强功能和全新特性。虽然无法一一列举所有更新,但让我们来看看一些最值得关注的亮点!
“
如果你还不了解 NestJS,它是一个 TypeScript Node.js 框架,可以帮助你构建企业级的高效可扩展的 Node.js 应用程序。
让我们直接开始吧!🐈
日志增强
在这个版本中,NestJS 的默认日志器 ConsoleLogger 获得了重大升级。它现在包括多项改进,如更好的深层嵌套对象和数组格式化、支持 Map 和 Set、以及自定义日志前缀的能力。但最突出的特性是新增的内置 JSON 日志支持。
你现在可以通过简单的配置来启用 JSON 格式的日志:
const app = await NestFactory.create(AppModule, {
logger: new ConsoleLogger({
json: true,
}),
});
将 json 选项设置为 true 可以确保日志以 JSON 格式输出,这对容器化环境来说是理想的选择。这使得无需第三方工具或库就能轻松解析和分析日志。
当启用 JSON 日志时,颜色默认是关闭的。但是,你可以通过设置 colors 选项为 true 来重新启用它,这在本地开发时更易于阅读:
const app = await NestFactory.create(AppModule, {
logger: new ConsoleLogger({
json: true,
colors: true,
}),
});
更灵活的微服务
在 NestJS 11 中,所有官方支持的微服务传输器(如 NATS、Kafka、Redis 等)都得到了显著改进。这些升级旨在为开发者提供更大的灵活性、可靠性和对代理服务的控制能力。
新的 unwrap 方法允许直接访问底层客户端实例,使你能够执行超出标准 NestJS API 的自定义操作:
import { NatsConnection } from 'nats';
const serviceRef = app.connectMicroservice({
transport: Transport.NATS,
options: {
// NATS 连接选项
},
});
const connection = serviceRef.unwrap
console.log(connection.info);
“
这里使用 NATS 作为示例,但 unwrap 方法适用于所有其他传输器。
此外,你现在可以使用新的 on 方法监听底层客户端发出的内部事件:
const serviceRef = app.connectMicroservice({
transport: Transport.NATS,
options: {
// NATS 连接选项
},
});
serviceRef.on
console.log('Client disconnected');
});
另一个强大的新增功能是 status 可观察流,它提供了客户端实例当前状态的实时更新:
const serviceRef = app.connectMicroservice({
transport: Transport.NATS,
options: {
// NATS 连接选项
},
});
serviceRef.status.subscribe((status) => {
console.log('Status:', status);
});
ClientProxy 类也提供了相同的 API 方法集:
constructor(
@Inject(MATH_SERVICE) private readonly client: ClientProxy
) {}
// 监听事件和状态
this.client.on('disconnect', () => console.log('Disconnected'));
this.client.status.subscribe(status => {
console.log('Status:', status);
});
更快的应用启动
在 NestJS 11 中,我们重新设计了模块不透明键生成过程以提高应用启动时间。
在之前的版本中,框架使用哈希函数通过序列化元数据来为动态模块生成不透明键。虽然这启用了某些内部优化,但也增加了不必要的复杂性和性能开销,特别是对于具有大量输入(如 JSON 文件)的动态模块,其中哈希生成速度慢且效率低下。
从 v11 开始,框架采用了更直接的方法。它现在使用对象引用而不是对整个模块元数据进行哈希来生成不透明键。
“
唯一可能注意到框架行为差异的情况是,当你的应用多次导入相同的动态模块(具有深度相等的配置)时。在这种情况下,框架现在会将这些模块视为单独的实例,而之前它们会合并为单个实例。对于依赖这种行为的用户,你可以将动态模块分配给一个变量并多次导入它,以确保在整个应用中使用相同的实例 const myModule = DynamicModule.forRoot({})。
Express v5 和 Fastify v5
NestJS 11 现在支持 Express 和 Fastify 的最新版本。虽然升级到 Fastify v5 对大多数用户来说应该很顺利,但由于底层库的重大变更,升级到 Express v5 可能需要一些调整。
Express v5 中最显著的更新之一是修改后的路径路由匹配算法。以下是路径字符串与传入请求匹配的新变化:
通配符 * 必须有名称,与参数 : 的行为匹配,使用 /*splat 或 /{*splat} 而不是 /*
不再支持可选字符 ?,改用大括号:/:file{.:ext}
不支持正则表达式字符
一些字符被保留以避免升级时的混淆 (()[]?+!),使用 \ 转义它们
参数名称现在支持有效的 JavaScript 标识符,或者像 :"this" 这样加引号
例如,以前在 Express v4 中工作的路由可能在 Express v5 中不工作:
@Get('users/*')
findAll() {
// 在 NestJS 11 中,这将自动转换为有效的 Express v5 路由
// 虽然它可能仍然工作,但在 Express v5 中不建议使用这种通配符语法
return 'This route should not work in Express v5';
}
要修复这个问题,你可以更新路由以使用命名通配符:
@Get('users/*splat')
findAll() {
return 'This route will work in Express v5';
}
“
注意,*splat 是一个命名通配符,它匹配不包含根路径的任何路径。如果你需要同时匹配根路径(/users),可以使用 /users/{*splat},将通配符包装在大括号中(可选组)。请注意,splat 只是通配符参数的名称,没有特殊含义。你可以将其命名为任何名称,例如 *wildcard。
其他有价值的更新
终止生命周期钩子(OnModuleDestroy、OnApplicationShutdown 等)的顺序已被反转
CacheModule 已更新为使用最新版本的 cache-manager(v6),现在使用 Keyv 作为键值存储的统一接口
在 @nestjs/common 中新增了 ParseDatePipe,使处理日期更容易
微服务选项现在可以从 DI 容器提供
在 @nestjs/common 中引入了 IntrinsicException,允许抛出不会被框架自动记录的异常
@nestjs/cqrs 现在支持请求作用域提供者和强类型命令、事件和查询
Reflector#getAll 和 Reflector#getAllAndMerge 现在将正确推断转换后的元数据类型
ConfigService#get 现在以不同的顺序读取配置值,允许用户从自定义配置工厂覆盖 process.env 值。此外,引入了 skipProcessEnv 选项,简化了配置值的封装(特别适用于测试)
从 Nest v10 迁移
要将现有项目迁移到 NestJS 11,请参考迁移指南[1]中提供的详细指导。这些步骤将帮助确保顺利过渡,解决所有必要的更改和更新。
享受 v11!
我们很期待看到你如何使用 NestJS 的最新版本。
请关注 Nest 的 X 账号 @nestframework 以获取所有最新公告!
参考资料
[1]
迁移指南: https://docs.nestjs.com/migration-guide
Node 社群
我组建了一个氛围特别好的 Node.js 社群,里面有很多 Node.js小伙伴,如果你对Node.js学习感兴趣的话(后续有计划也可以),我们可以一起进行Node.js相关的交流、学习、共建。下方加 考拉 好友回复「Node」即可。
“分享、点赞、在看” 支持一波👍