简介
Koa是Express团队创建的一个新的网络框架。它旨在成为 Express 的现代和简约版本。
它的一些特点是支持并依赖于 JavaScript 的新特性,如 generators 和 async/await 。Koa 也不附带任何中间件,但可以使用自定义插件和现有插件进行扩展。
在本文中,您将进一步了解 Koa 框架,并构建一个应用程序来熟悉其功能和理念。
先决条件
如果您想继续阅读本文,您需要
- 本地安装 Node.js,您可以按照如何安装 Node.js 并创建本地开发环境进行安装。
- 您还需要掌握 JavaScript 和 ES6 语法。
<$>[注] 注: 本教程已从 Koa 1.0 修订为 Koa 2.0。请参阅 迁移文档 更新您的 1.0 实现。 <$>
本教程使用 Node v15.14.0、npm
v7.10.0、koa
v2.13.1、@koa/router
v10.0.0 和koa-ejs
v4.3.0 进行了验证。
步骤 1 - 设置项目
首先,为项目创建一个新目录。在终端复制并运行下面的命令即可:
1mkdir koa-example
<$>[注]
注: 您可以给项目取任何名称,但本文将使用 koa-example
作为项目名称和目录。
<$>
至此,您已创建了项目目录 koa-example
。导航到新创建的项目目录。
1cd koa-example
然后,从目录中初始化 Node 项目。
1npm init -y
运行 "npm init "命令后,你将得到一个包含默认配置的 "package.json "文件。
接下来,运行此命令安装 Koa:
1npm install [email protected]
您的应用程序现在可以使用 Koa 了。
第 2 步 - 创建 Koa 服务器
首先,创建 index.js
文件。然后,使用代码编辑器打开 index.js
文件并添加以下代码行:
1[label index.js]
2'use strict';
3
4const Koa = require('koa');
5const app = new Koa();
6
7app.use(ctx => {
8 ctx.body = 'Hello World';
9});
10
11app.listen(1234);
在上面的代码中,您创建了一个在端口 1234
上运行的 Koa 应用程序。您可以使用以下命令运行应用程序:
1node index.js
并访问 "http://localhost:1234 "上的应用程序。
第 3 步 - 添加路由和视图渲染
如前所述,Koa.js 并不包含任何中间件,与其前身 Express 不同的是,它默认不处理路由。
为了在 Koa 应用程序中实现路由,你需要在 Koa 中安装一个路由中间件库 Koa Router。
打开终端窗口,运行以下命令:
1npm install @koa/[email protected]
<$>[注]
注: 以前推荐使用 koa-router
软件包,但现在 @koa/router
是官方支持的软件包。
<$>
要在应用程序中使用路由器,请修改 index.js
文件:
1[label index.js]
2'use strict';
3
4const Koa = require('koa');
5const Router = require('@koa/router');
6
7const app = new Koa();
8const router = new Router();
9
10router.get('koa-example', '/', (ctx) => {
11 ctx.body = 'Hello World';
12});
13
14app
15 .use(router.routes())
16 .use(router.allowedMethods());
17
18app.listen(1234);
这段代码在应用程序的基本 URL (http://localhost:1234
)上定义了一个路由,并将此路由注册到 Koa 应用程序中。
有关 Koa.js 应用程序中路由定义的更多信息,请访问 Koa 路由器库文档。
如前所述,Koa 是一个极简框架,因此,要使用模板引擎实现视图渲染,您必须安装一个中间件库。有多个中间件库可选,但本文将使用 Koa ejs。
打开终端窗口,运行以下命令:
1npm install [email protected]
接下来,修改你的 index.js
文件,用下面的代码段注册你的模板:
1[label index.js]
2'use strict';
3
4const Koa = require('koa');
5const Router = require('@koa/router');
6const render = require('koa-ejs');
7const path = require('path');
8
9const app = new Koa();
10const router = new Router();
11
12render(app, {
13 root: path.join(__dirname, 'views'),
14 layout: 'index',
15 viewExt: 'html',
16 cache: false,
17 debug: true
18});
19
20router.get('koa-example', '/', (ctx) => {
21 ctx.body = 'Hello World';
22});
23
24app
25 .use(router.routes())
26 .use(router.allowedMethods());
27
28app.listen(1234);
在模板注册中,您定义了视图文件的根目录、视图文件的扩展名和基本视图文件(其他视图对其进行扩展)。
现在您已经注册了模板中间件,请修改路由定义以渲染模板文件:
1[label index.js]
2// ...
3
4router.get('koa-example', '/', (ctx) => {
5 let koalaFacts = [];
6
7 koalaFacts.push({
8 meta_name: 'Color',
9 meta_value: 'Black and white'
10 });
11
12 koalaFacts.push({
13 meta_name: 'Native Country',
14 meta_value: 'Australia'
15 });
16
17 koalaFacts.push({
18 meta_name: 'Animal Classification',
19 meta_value: 'Mammal'
20 });
21
22 koalaFacts.push({
23 meta_name: 'Life Span',
24 meta_value: '13 - 18 years'
25 });
26
27 koalaFacts.push({
28 meta_name: 'Are they bears?',
29 meta_value: 'No'
30 });
31
32 return ctx.render('index', {
33 attributes: koalaFacts
34 });
35})
36
37// ...
您的基本路由会渲染 views
目录中的 index.html
文件。
现在,创建此目录和文件。打开 index.html
并添加以下代码行:
1[label views/index.html]
2<h2>Koala - a directory Koala of attributes</h2>
3<ul class="list-group">
4 <% attributes.forEach( function(attribute) { %>
5 <li class="list-group-item">
6 <%= attribute.meta_name %> - <%= attribute.meta_value %>
7 </li>
8 <% }) %>
9</ul>
现在,当运行应用程序并在网络浏览器中观察时,将显示如下内容:
1[secondary_label Output]
2Koala - a directory Koala of attributes
3Color - Black and white
4Native Country - Australia
5Animal Classification - Mammal
6Life Span - 13 - 18 years
7Are they bears? - No
有关使用 koa-ejs
模板中间件的更多选项,请访问库文档。
步骤 4 - 处理错误和回复
Koa 通过在入口点文件中提前定义错误中间件来处理错误。错误中间件必须尽早定义,因为只有在错误中间件之后定义的中间件产生的错误才会被捕获。
以您的 index.js
文件为例,对代码进行以下修改:
1[label index.js]
2'use strict';
3
4const Koa = require('koa');
5const Router = require('@koa/router');
6const render = require('koa-ejs');
7const path = require('path');
8
9const app = new Koa();
10const router = new Router();
11
12app.use(async (ctx, next) => {
13 try {
14 await next()
15 } catch(err) {
16 console.log(err.status)
17 ctx.status = err.status || 500;
18 ctx.body = err.message;
19 }
20});
21
22// ...
该代码块将捕获应用程序执行过程中抛出的任何错误。
您可以在定义的路由的函数体中抛出一个错误来测试这一点:
1[label index.js]
2// ...
3
4router.get('error', '/error', (ctx) => {
5 ctx.throw(500, 'internal server error');
6});
7
8app
9 .use(router.routes())
10 .use(router.allowedMethods());
11
12app.listen(1234);
现在,当运行应用程序并在网络浏览器中观察 /error
时,将显示如下内容:
1[secondary_label Output]
2internal server error
Koa 响应对象通常嵌入在其上下文对象中。让我们使用路由定义来展示一个设置响应的示例:
1[label index.js]
2// ...
3
4router.get('status', '/status', (ctx) => {
5 ctx.status = 200;
6 ctx.body = 'ok';
7})
8
9app
10 .use(router.routes())
11 .use(router.allowedMethods());
12
13app.listen(1234);
现在,当运行应用程序并在网络浏览器中观察 /status
时,将显示如下内容:
1[secondary_label Output]
2ok
您的应用程序现在可以处理错误和响应。
结论
本文简要介绍了 Koa 以及如何在 Koa 项目中实现一些常见功能。Koa 是一个简约而灵活的框架,它可以扩展的功能比本文介绍的更多。由于其未来性与 Express 相似,有些人甚至将其描述为 Express 5.0。