初始化实例代理上下文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

    1. ## 安装依赖
    2. npm i
    3. ## 执行 demo
    4. npm run start
    5. ## 最后启动chrome浏览器访问
    6. ## http://127.0.0.1:3000/index
    7. ## http://127.0.0.1:3000/hello

    解读

    1. const path = require('path');
    2. const fs = require('fs');
    3. function view(app, opts = {}) {
    4. const {baseDir = ''} = opts;
    5. // 将需要的属性或者方法 `view` 挂载在 `app.context` 上,`app.context.view`
    6. app.context.view = function(page = '', obj = {}) {
    7. let ctx = this;
    8. let filePath = path.join(baseDir, page);
    9. if (fs.existsSync(filePath)) {
    10. let tpl = fs.readFileSync(filePath, 'binary');
    11. ctx.body = tpl;
    12. } else {
    13. ctx.throw(404);
    14. }
    15. };
    16. }
    17. module.exports = view;

    使用

  • 使用目录

    1. .
    2. ├── example.js
    3. ├── index.js
    4. └── views
    5. ├── hello.html
    6. └── index.html
    1. // example.js
    2. const Koa = require('koa');
    3. const path = require('path');
    4. const view = require('./index');
    5. // 初始化一个`Koa`实例 `let app = new Koa()`
    6. const app = new Koa();
    7. // 将需要的属性或者方法 `view` 挂载在 `app.context` 上,`app.context.view`
    8. view(app, {
    9. baseDir: path.join(__dirname, 'views')
    10. });
    11. app.use(async ctx => {
    12. await ctx.view(`${ctx.path}.html`, {
    13. title: 'index page'
    14. });
    15. });
    16. app.listen(3000, () => {
    17. console.log('[demo] jsonp is starting at port 3000');
    18. });

    附录

    参考

  • https://github.com/koajs/ejs