前言
狭义中间件区别于请求/响应拦截的另一种方式是上下文context代理。
上下文context代理分成两种
- 实例代理上下文context
- 请求过程代理上下文context
这里先将第一种代理方式——实例代理上下文context实现步骤,实例代理的比较有代表性的中间件是官方提 koa-ejs
中间件,把渲染的方法挂载在Koa
实例app
的app.context
属性中。
常见化实例代理上下文context实现步骤
- 初始化一个
Koa
实例let app = new Koa()
- 将需要的属性或者方法
demo
挂载在app.context
上,app.context.demo
- 在
app.use()
中间件直接使用ctx.demo
方法或属性
这里我们实现最简单的模板渲染中间件 view
,模仿koa-ejs
的基本能力。
实现步骤
view
的实现步骤
- step 01 初始化一个
Koa
实例let app = new Koa()
- step 02 将需要的属性或者方法
view
挂载在app.context
上,app.context.view
step 03 在
app.use()
中间件直接使用ctx.view
方法或属性渲染模板实现源码
demo源码
https://github.com/chenshenhai/koajs-design-note/tree/master/demo/chapter-05-01## 安装依赖
npm i
## 执行 demo
npm run start
## 最后启动chrome浏览器访问
## http://127.0.0.1:3000/index
## http://127.0.0.1:3000/hello
解读
const path = require('path');
const fs = require('fs');
function view(app, opts = {}) {
const {baseDir = ''} = opts;
// 将需要的属性或者方法 `view` 挂载在 `app.context` 上,`app.context.view`
app.context.view = function(page = '', obj = {}) {
let ctx = this;
let filePath = path.join(baseDir, page);
if (fs.existsSync(filePath)) {
let tpl = fs.readFileSync(filePath, 'binary');
ctx.body = tpl;
} else {
ctx.throw(404);
}
};
}
module.exports = view;
使用
使用目录
.
├── example.js
├── index.js
└── views
├── hello.html
└── index.html
// example.js
const Koa = require('koa');
const path = require('path');
const view = require('./index');
// 初始化一个`Koa`实例 `let app = new Koa()`
const app = new Koa();
// 将需要的属性或者方法 `view` 挂载在 `app.context` 上,`app.context.view`
view(app, {
baseDir: path.join(__dirname, 'views')
});
app.use(async ctx => {
await ctx.view(`${ctx.path}.html`, {
title: 'index page'
});
});
app.listen(3000, () => {
console.log('[demo] jsonp is starting at port 3000');
});
附录
参考