Skip to content

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

  • 关注公众号:陈随易,获取最新文章推送 (很多内容只在公众号发布)
  • 个人网站 1️⃣:https://chensuiyi.me
  • 个人网站 2️⃣:https://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 的参数操作在浏览器端和服务器变得一致。


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

何以解忧,唯有代码。不忘初心,方得始终。