Nodejs 框架 Koa 介绍和使用

对于 Nodejs 框架和开源软件来说,2018 年是非常有趣的一年。开发者社区讨论了企业赞助对开源项目的作用以及如何维护那些没有经济支持却有数百万人使用的项目。在 Github 星标数量方面,Sails、Koa 和 Express 明显高于其他框架。

Nodejs 框架的 Github star 数量统计

不得不说,Express 和 Koa 是 Nodejs 目前炙手可热的2大框架。

Express 诞生已有时日, 是一个基于 Nodejs 平台的极简、灵活的 web 应用开发框架,主要基于 Connect 中间件,并且自身封装了路由、视图处理等功能,使用人数众多。

Koa 相对更为年轻, 是 Express 原班人马基于 ES6 新特性重新开发的框架,主要基于 co 中间件,框架自身不包含任何中间件,很多功能需要借助第三方中间件解决,但是由于其基于 ES6 generator 特性的异步流程控制,解决了 “callback hell” 和麻烦的错误处理问题,大受开发者欢迎。

什么是 koa 框架

koa 是一个基于 Nodejs 实现的一个新的 web 框架,它是由 Express 框架的原班人马打造的。它的特点是优雅、简洁、表达力强、自由度高。它更 Express 相比,它是一个更轻量的 Nodejs 框架,因为它所有功能都通过插件实现,这种插拔式的架构设计模式,很符合 Unix 哲学。

本文所用的框架是 koa2,它跟 koa1 不同,koa1 使用的是 generator+co.js 的执行方式,而 koa2 中使用了 async/await,因此本文的代码和 demo 需要运行在 node 8 版本及其以上,如果读者的 node 版本较低,建议升级或者安装 babel-cli,用其中的 babel-node 来运行本文涉及到的代码。

创建 koa 项目

初始化 package.json 文件

首先使用 npm init 命令创建一个默认的 package.json 文件:

npm init -y

这里的 -y 参数是为了默认选择是(y),然后创建好后的文件内容如下:

{
  "name": "nodejs-post3",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

一个 package.json 文件默认必须包括 nameversion,例如:

{
  "name": "nodejs-post3",
  "version": "1.0.0"
}

关于这些配置的含义如下:

  • name: 当前目录名。
  • version: 初始化的版本,默认总是 1.0.0.
  • description: 一个描述,默认为 “”.
  • main: 默认的总是 index.js.
  • scripts: 默认情况下创建一个空的测试脚本。
  • keywords: 空的
  • author: 空的
  • license: ISC

还可以为 init 命令设置一些有用的几个配置选项:

npm set init.author.email "wombat@npmjs.com"
npm set init.author.name "ag_dubs"
npm set init.license "MIT"

安装 koa

执行 npm 安装:

npm install koa --save

然后你会发现目录中多了一个 node_modules 文件夹和一个 package-lock.json 文件。

先说说这个 package-lock.json 文件吧,这个文件一般不需要你手动修改,这个 package-lock.json 是在 npm install 时候生成一份文件,用以记录当前状态下实际安装的各个 npm package 的具体来源和版本号。可以锁定安装时的包的版本号,并且需要上传到 git,以保证其他人在 npm install 时大家的依赖能保证一致。所以在协同开发过程中这个文件有更新我们就需要执行一下 npm install 更新。

这个 node_modules 文件夹中放置的就是依赖的这些库的源文件,你会发现和上面的 package-lock.json 中的文件目录所对应。然后我们还发现了一点变化就是 package.json 文件中新增了如下代码:

"dependencies": {
    "koa": "^2.8.1"
}   

创建示例工程

接下来创建一个 app.js 文件,内容如下:

const Koa = require('koa');

//创建一个 Koa 对象表示 web app 本身
const app = new Koa();

//对于任何请求,app将调用该异步函数处理请求:
app.use(async (ctx, next) => {
    await next();
    ctx.response.type = 'text/html';
    ctx.response.body = '<h1>Hello, koa2!</h1>';
});

// 在端口3000监听:
app.listen(3000);

console.log('app started at port 3000...');

然后执行 node app.js 启动服务,在浏览器输入 localhost:3000 访问,结果如下:

浏览器访问结果

我们可以换个方式来启动,编辑 package.json 的 script 如下:

"scripts": {
  "start": "node app.js"
}

然后执行如下命令(下面的 start 就是 script 中配置的):

npm start

这个 app.use() 的作用是将给定 function 当做中间件加载到应用中。 async 函数不是 kos 的函数,而是 ES2017 标准引入的函数。这个 async 函数其实是另一个函数 Generator 的语法糖,这个Generator 函数是 ES6 提供的一种异步编程解决方案。本文出自水寒的博客,转载请说明出处:https://dp2px.com

引入 koa-router 路由

接下来我们修改一下上面的代码,引入 koa-router 路由来实现。

先安装 koa-router:

npm install koa-router

安装好后我们修改上面的 app.js 中的代码:

const http = require('http')
const Koa = require('koa');
const Router = require('koa-router')

const app = new Koa();

const router = new Router()
router.prefix('/api')
router.get('/test', async(ctx, next) => {
        await next();
        ctx.response.type = 'text/html';
        ctx.response.body = '<h1>Hello, koa2!</h1>';
    });

app.use(router.routes(), router.allowedMethods())

const server = http.createServer(app.callback());
server.listen(3000);

console.log('app started at port 3000...');

可以通过访问 localhost:3000/api/test 请求我们上面设置的 /test 路由路径。

今天就写到这里吧,一个非前端程序员写这个还是蛮费脑子的。不过不要担心,关于 koa 的更多用法,我们后面会通过几篇文章来逐一说明,并且会研究其实现的原理。

本系列源码在 GitHub 仓库:https://github.com/lxqxsyu/NodejsStudy