func-package

函数库, 面向复杂业务场景的 js 类库

view实现

初始化实例代理上下文context 实现

前言

狭义中间件区别于请求/响应拦截的另一种方式是上下文context代理。

上下文context代理分成两种

  • 实例代理上下文context
  • 请求过程代理上下文context

这里先将第一种代理方式——实例代理上下文context实现步骤,实例代理的比较有代表性的中间件是官方提 koa-ejs 中间件,把渲染的方法挂载在Koa实例appapp.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');
});

附录

参考