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

  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. });

附录

参考