长跑8年,Node.js框架Koa v3.0终发布

大家好,我是农村程序员,独立开发者,行业观察员,前端之虎陈随易。

  • 关注公众号:陈随易,获取最新文章推送 (很多内容只在公众号发布)
  • 个人网站 1️⃣:chensuiyi.me
  • 个人网站 2️⃣:me.yicode.tech
  • 加入交流群,公众号或者个人网站联系我即可

我会在这里分享关于 编程技术独立开发行业资讯思考感悟 等内容。

所有文章都是古法手打,经过了深度思考和总结,不含 AI 添加剂,请放心食用,一起灵魂交流。

如果本文能给你提供启发或帮助,欢迎动动小手指,一键三连 (点赞评论转发),给我一些支持和鼓励,谢谢。


Node.js 有两大家喻户晓的 Web 开发框架,一个是 express,另一个则是 koa

两者有个共同点,那就是简单到了极致,几乎没有多少学习成本,为 Node.js 的推广和传播立下了汗马功劳。

随着技术的发展,越来越多的新框架涌现出来,提供了更为完善的生态和功能,这两位老将也逐渐廉颇老矣,尚能饭否。

作为一个长期关注技术资讯的博主,曾一度以为 express v5.0koa v3.0 不会问世,因为其中有些版本更新间隔长达 1-2年之久。

不过最终呢,两者在2024年和2025年,都迎来了一个全新的大版本更新。

从官方计划来看,koa v3.0 的发布计划可以追溯到2017年,如今8年过去了,新的篇章已经开始起航,而8年的长跑,也终于落幕。

OK,碎碎念就到这里,接下来一起看看,koa v3.0 都更新了什么内容吧。

最小支持 Node.js 版本为 v18

Node.js v18(2022年4月发布) 是一个比较特殊的版本,引入了原生的 Fetch API(实验性),新增了 node:test(实验性) 测试模块,并作为长期支持的稳定版本维护,是很多项目目前依旧保持的稳定版本。

也在一定程度上,标志着 Node.js 发展更为激进的开端。

移除 .redirect('back'),添加 .back(fallback_url)

这也是2017年的提案,由于 v2 版本即将发布,这个提案直到 v3 版本才尘埃落定。

不要在锚点引用中渲染重定向值

js 复制代码
assert.strictEqual(ctx.body, `Redirecting to <a href="${url}">${url}</a>.`);
👇
assert.strictEqual(ctx.body, `Redirecting to ${url}.`);

简而言之就是,以前重定向 (redirect()),会渲染一个 a 标签,现在不会了。


req.origin 返回值调整

如果 headerorigin 值,则直接返回该值,而不是当前的主机名 (hostname)。

这个调整,给 CORS 跨域问题提供了更准确的请求源识别,也进一步简化了 CORS 中间件的实现。

删除特殊的 ENOENT 支持

在以前的版本中,Koa 对某些文件流 (如 fs.createReadStream) 的 ENOENT 错误进行了特殊处理。

ENOENT 代表文件不存在,默认情况下,Koa 会捕获这种错误并返回一个通用响应,而不需要开发者显式处理。

本次更新移除了对 ENOENT 错误的特殊支持,要求开发者手动检查并处理流的错误。这是为了让流的错误处理逻辑更具一致性和可控性。

更新前:

js 复制代码
ctx.body = fs.createReadStream('non-existent-file.txt');

更新后:

js 复制代码
app.use(async (ctx, next) => {
    await next();

    if (ctx.body?.readable && typeof ctx.body?.pipe === 'function') {
        await new Promise((resolve, reject) => {
            ctx.body.on('readable', () => resolve());
            ctx.body.on('error', (err) => reject(err)); // 必须处理错误
        });
    }
});

这是一个重大改动 (breaking change),目的是让开发者对流的错误处理更加明确和可控。

虽然移除了方便性,但增加了灵活性和一致性,符合更好的开发实践。

支持自定义流

js 复制代码
import archiver from 'archiver'

const archive = archiver('zip')
const stream = ...
archive.append(stream, { name: 'archive.zip'})

res.body = archive

也即是说,可以用第三方流处理包来作为返回了。

支持 WHATWG 响应体

WHATWG 是什么?可以理解为 网络世界的规则制定者,定义了 HTML、DOM、Fetch API 等网络技术如何工作的规则。

本次更新,表示 koa v3 已经可以使用与浏览器中相同的 Response 对象格式。

这样一来,Koa 就能与最新的 Web 标准保持一致,让开发者可以用相似的方式处理前端和后端的 HTTP 响应,简化了全栈开发体验。

使用 asyncLocalStorage 获取当前应用上下文

示例:

js 复制代码
const ctx = app.currentContext;

app.currentContext 是一个让你可以在任何地方 (不仅仅是中间件内部) 获取当前请求的上下文信息。

想象你有一个全局的 魔法抽屉,无论你的代码在哪里执行,都可以拿到当前正在处理的请求信息。

之前的问题:

js 复制代码
// Koa v2 方式
app.use(async (ctx, next) => {
    // 只有在这里能访问 ctx

    // 如果调用其他函数,必须手动传递 ctx
    someFunction(ctx);
    await next();
});

function someFunction(ctx) {
    // 必须通过参数获取 ctx
}

现在的优势:

js 复制代码
// Koa v3 新方式
app.use(async (ctx, next) => {
    // 使用中间件
    await next();
});

// 在任何其他文件或函数中
function someUtility() {
    const ctx = app.currentContext; // 直接获取当前请求上下文!
    const userId = ctx.request.body.userId;
    // ...处理逻辑
}

使用场景:

  • 工具函数:不需要每次都传递 ctx 参数。
  • 日志记录:轻松在日志中包含当前请求信息。
  • 错误处理:在任何地方捕获错误时能获取请求详情。
  • 第三方库集成:让第三方库能感知当前请求。

query stringURLSearchParams 替代

也是面向标准的一次更新,让 URL 的参数操作在浏览器端和服务器变得一致。


感谢阅读,本文由编程记者 前端之虎陈随易 撰稿,转载请保留顶部信息。

相关推荐
前端大白话几秒前
前端崩溃瞬间救星!10 个 JavaScript 实战技巧大揭秘
前端·javascript
loveoobaby2 分钟前
Shadertoy着色器移植到Three.js经验总结
前端
Rabbb3 分钟前
C# JSON属性排序、比较 Newtonsoft.Json
后端
L2ncE4 分钟前
【LanTech】DeepWiki 101 —— 以后不用自己写README了
人工智能·程序员·github
蓝易云4 分钟前
在Linux、CentOS7中设置shell脚本开机自启动服务
前端·后端·centos
浩龙不eMo5 分钟前
前端获取环境变量方式区分(Vite)
前端·vite
一千柯橘11 分钟前
Nestjs 解决 request entity too large
javascript·后端
土豆骑士16 分钟前
monorepo 实战练习
前端
土豆骑士17 分钟前
monorepo最佳实践
前端
见青..18 分钟前
【学习笔记】文件包含漏洞--本地远程包含、伪协议、加密编码
前端·笔记·学习·web安全·文件包含