学了一段时候的 js 了,倏忽想实践一下。恰好公司有个小的项目要做,就顺手拿 Koa2 来做了。真是不做不晓得,做了想不到。踩了一堆新手坑。
首次打仗 Koa2
在晓得 Koa2 之前,我也相识过 Express,惋惜并没有实战用过。厥后人人都说 Koa 是一个比 Express 更牛X的东西,因而在好(作)奇(死)心作怪下,直接去用 Koa2 了。厥后证实确实是作死,底本用 PHP 一天就可以写完东西,愣是让我搞了三天。
装配
近来 Node.js V8 宣布了,原生支撑 async
和 await
调用了,所以直接把 Node.js 晋级了一下。
依据 Koa2 的教程,装配很简单,我是运用的 yarn 的(还真是比 npm 快)。
yarn add koa
默许就装了 Koa 2.2。然后装完了,实在我是一脸懵逼的,文档上说如许用。
const Koa = require('koa')
const app = new Koa()
// response
app.use(ctx => {
ctx.body = 'Hello Koa'
})
app.listen(3000)
我照着代码写了下来,确实胜利了。然则,难不成我要把一切的逻辑写在 app.use
里?
中间件
我觉得我受到了惊吓,吓得我赶忙往下看文档。本来 Koa2 是一个中间件模子。app.use
可以有许多,每一个 app.use
会注册一个中间件,这个中间件是详细做事情的。每一个中间件是顺次实行的。一个典范的洋葱图可以诠释这一切。
那末,上面的实例就可以够改形成如许。
app.use(async (ctx, next) => {
await next()
ctx.body = 'Hello Koa'
})
根据上面的洋葱头,以心为单元,next的两侧的语句分别在洋葱的左边和右边举行实行,颇像 Laravel
的中间件。
就如许,我晓得了,一切的操纵没必要写在同一个 app.use
里。然则,下一个题目来了,我要把一切的逻辑都写再一个文件里?说好的 MVC 呢?没有 MVC 也叫做框架?Are you kidding me?(好吧厥后发明本来 Koa2 并非一个装配做网站的框架)
既然没有 MVC,那就本身着手饱食暖衣吧。
路由
首先要处置惩罚的就是路由的题目。不过,由因而第一次用这货写项目,时候紧,(伪)任务重,看了文档后发明,本来另有一个中间件列表的链接,内里有种种开源的中间件。我想你们肯定隔着屏幕都能听到我发出杠铃般的笑声了。有一个中间件异常棒,叫做 koa-router。这货是这么用的。
var Koa = require('koa')
var Router = require('koa-router')
var app = new Koa()
var router = new Router()
router.get('/', function (ctx, next) {
// ctx.router available
});
app.use(router.routes())
虽然是把逻辑和 app.use
分开了,然则,彷佛照样没有处理适才的题目。说好的 MVC 也没有涌现。因而我再去找了找,竟然没有 Controller
的中间件。我一下就懵逼了,玩脱了?另有一天啊我的宝贝儿。经由我半秒钟的郑重思索,我照样用 koa-router
本身完成一个控制器吧。
Controller
const fs = require('fs')
function addRoutes(router, routes) {
for (let route in routes) {
switch (route.method) {
case: 'post':
router.post(route.uri, route.fn)
console.log(`Register post url: ${route.uri}`)
break
case: 'get':
router.get(route.uri, route.fn)
console.log(`Register get url: ${route.uri}`)
break
default:
console.log(`Invalid url: ${route}`)
}
}
}
function addControllers(router) {
let files = fs.readdirSync(__dirname + '/controllers')
let controllerFiles = files.filter(f => {
return f.endsWith('.js')
})
for (let controllerFile in controllerFiles) {
console.log(`process controller: ${controllerFile}...`)
let routes = require(__dirname + '/controllers')
addRoutes(router, routes)
}
}
module.exports = () => {
let router = require('koa-router')()
addControllers(router)
return router.routes()
}
我经由过程在 controllers
文件夹中,建立多少 js
文件来作为 Controller
来运用。这里轻微参考了下 廖雪峰的文章。
然后,我们只需要在 controllers
文件夹中增加适宜的文件就可以够了。比方我们增加一个文件叫做 chart.js
,然后如许写代码。
let hello = async (ctx, next) => {
ctx.body = 'Hello the fucking world!'
}
module.exports = [
{
method: 'get',
uri: 'hello',
fn: hello,
}
]
末了再在 app.js
注册中间件即可。
除此之外,我们还需要可以处置惩罚 ctx
里的内容,因为它内里存储的是原始的内容。照样因为时候紧,任(填)务(坑)重(急),我用了 koa-bodyparser。
const bodyParser = require('koa-bodyparser')
app.use(bodyParser())
这里要提示的是,这货肯定要放在处置惩罚路由中间件的前面。
Model
MVC
的 C
已处理了,接下来就要处理 M
的题目了。这里我用的是 Sequelize。这个 ORM
和大多数的 ORM
都差不多,所以在这里此次没有踩到什么坑。我在根目次下新建了一个 config.js
的配置文件,然后新建了 model.js
用来定义模子。
const Sequelize = require('sequelize')
const config = require('./config').databases
...
module.exports = {
//models
}
View
视图,我是运用了一个中间件叫做 koa-view。因为它运用的是 Nunjucks 模板引擎,关于写 PHP
的我相对熟习一点。
const view = require('koa-view')
const app = Koa()
app.use(view(__dirname + '/views'))
//controller
let Hello = (ctx, next) => {
ctx.render('hello', datas)
}
只要在 ‘views’ 文件夹中定义相对应的 html 文件即可。
跋文
此次的尝试,终究在我的修修补补中,搞出了一个大略的 MVC
模子。赶在了 deadline 前完成,真是一波三折啊。进修新技术,就是如许,要实践嘛= =下面给出我的项目目次作参考
koa2/
|
+- controllers/
| |
| +- chart.js
| ...
|
+- static/
| |
| +- js/
| ...
| |
| +- style/
| |
| +- img
| ...
|
+- views/
| |
| +- game.html
| ...
|
+- app.js
|
+- config.js
|
+- controller.js
|
+- model.js
|
+- package.json
|
+- yarn.lock
|
+- node_modules/
菜鸟作品,若有毛病请斧正,不胜感激。
假如你喜欢我的文章,那就请我喝杯奶茶吧~