koa
koa 是由 Express 原班人马打造的,致力于成为一个更小、更富有表现力、更健壮的 Web 框架。使用 koa 编写 web 应用,通过组合不同的 generator,可以免除重复繁琐的回调函数嵌套,并极大地提升错误处理的效率。koa 不在内核方法中绑定任何中间件,它仅仅提供了一个轻量优雅的函数库,使得编写 Web 应用变得得心应手。
koa2是koa的第二个大版本,目前github最新版本是2.2.0,已经比较成熟,且本文基于该版本。
为什么写这篇文章
想用node搞一个自己的服务器,选择是Express或者koa。想用Express是因为平时用的多,比较熟悉。但是后来一想,要搞就搞最新的,并且koa和Express是同一伙人开发的,入手应该不难。但是显示总是能给人「惊喜」,真是各种艰难困苦,花了尽5个小时才大概把框架搭好。虽然过程很坎坷,但是终于弄出来了不是,必须“以文记之,以告后来人”。
开发环境搭建(Node多版本管理)
IDE: WebStorm 2017.1.2
Node.js: v7.10.0
- Node 安装:
koa需要node v7.6.0+,虽然可以通过装 babel 使用旧版本,但是个人还是觉得用新版本的好。所以我使用一个node版本管理工具使我可以同时使用多个版本的node:n
# 全局安装
$ npm install -g n
# 安装最新版本
$ n latest
# 安装特定版本
$ n 6.9.2
# 显示已安装版本,键盘方向可以选择默认版本
$ n
node/6.9.2
ο node/7.10.0
查看当前默认node版本:
$ node -v
v7.10.0
-
WebStorm设置:
启用ECMAScript 6:
干掉一些代码中出现的奇怪波浪线:
确认项目使用的node版本:
项目结构
虽然我用的是koa,但是因为刚从Express过来,所以项目结构还是按照Express的想法来的:
代码部分
- package.json:
{
"name": "node-koa-server",
"version": "0.0.0",
"private": true,
"scripts": {
"start": "node app.js"
},
"engines": {
"node": "^7.6.0"
},
"dependencies": {
"debug": "~2.2.0",
"koa": "^2.2.0",
"koa-bodyparser": "^3.2.0",
"koa-convert": "^1.2.0",
"koa-json": "^2.0.2",
"koa-logger": "^2.0.1",
"koa-onerror": "^1.2.1",
"koa-router": "^7.1.1",
"koa-static": "^3.0.0",
"koa-views": "^5.2.1",
"nunjucks": "^2.4.2"
}
}
- app.js:
const Koa = require('koa');
const views = require('koa-views');
const json = require('koa-json');
const bodyparser = require('koa-bodyparser')();
const logger = require('koa-logger');
const onerror = require('koa-onerror');
const nunjucks = require('nunjucks');
const index = require('./routes/index');
const app = new Koa();
// view engine setup
nunjucks.configure('views', { autoescape: true });
//views with nunjucks
app.use(views(__dirname + '/views', {
map: { html: 'nunjucks' }
}));
// middle wares
app.use(bodyparser);
app.use(json());
app.use(logger());
app.use(require('koa-static')(__dirname + '/public'));
// logger
app.use(async function (ctx, next) {
const start = new Date();
await next();
const ms = new Date() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});
// routes
app.use(index.routes(), index.allowedMethods());
// error handler
onerror(app);
const port = 3000;
app.listen(port);
console.info('启动服务器在 http://localhost:' + port);
koa的这些控件作用请自行google,你能得到很详细的答案,这里不再赘述。
- index.js:
const router = require('koa-router')();
router.get('/', async (ctx, next) => {
await ctx.render('templates/index', {
title: 'Hello Koa 2!'
})
});
router.get('/string', async (ctx, next) => {
ctx.body = 'koa2 string';
});
router.get('/json', async (ctx, next) => {
ctx.body = {
title: 'koa2 json'
}
});
module.exports = router;
- default.html:
{% block title %}{% endblock %}
{% block header %}{% endblock %}
{% block body %}{% endblock %}
{% block scripts %}{% endblock %}
- index.html:
{% extends "layouts/default.html" %}
{% block title %}{{title}}{% endblock %}
{% block body %}
{{content}}
{% endblock %}
运行结果
运行app.js,在浏览器输入地址http://localhost:3000:
以上,代码可参阅这里