View 插件开发


    本文将阐述框架对 View 插件的规范约束, 我们可以依此来封装对应的模板引擎插件。以下以 egg-view-ejs 为例。

    • 遵循
    • 插件命名约定以 开头
    • package.json 配置如下,插件名以模板引擎命名,比如 ejs

      1. {
      2. "name": "egg-view-ejs",
      3. "eggPlugin": {
      4. "name": "ejs"
      5. },
      6. "keywords": [
      7. "egg",
      8. "egg-plugin",
      9. "egg-view",
      10. ],
      11. }
    • 配置项也以模板引擎命名

      1. // config/config.default.js
      2. module.exports = {
      3. ejs: {},
      4. };

    接下来需提供一个 View 基类,这个类会在每次请求实例化。

    View 基类需提供 renderrenderString 两个方法,支持 generator function 和 async function(也可以是函数返回一个 Promise)。render 方法用于渲染文件,而 方法用于渲染模板字符串。

    render 方法的三个参数

    • filename: 是完整的文件的路径,框架查找文件时已确认文件是否存在,这里不需要处理
    • locals: 渲染所需的数据,数据来自 app.localsctx.locals 和调用 render 方法传入的。框架还内置了 ctxrequest, ctx.helper 这几个对象。
    • viewOptions: 用户传入的配置,可覆盖模板引擎的默认配置,这个可根据模板引擎的特征考虑是否支持。比如默认开启了缓存,而某个页面不需要缓存。

    renderString 方法的三个参数

    • tpl: 模板字符串,没有文件路径。
    • locals: 同 render
    • viewOptions: 同 render

    根据上面的命名约定,配置名一般为模板引擎的名字,比如 ejs。

    插件的配置主要来自模板引擎的配置,可根据具体情况定义配置项,如 ejs 的配置

    1. // config/config.default.js
    2. module.exports = {
    3. ejs: {
    4. cache: true,
    5. }
    6. };

    框架本身提供了 ctx.helper 供开发者使用,但有些情况下,我们希望对 helper 方法进行覆盖,仅在模板渲染时生效。

    1. <div>{{ helper.shtml(data.content) | safe }}</div>

    但如上代码所示,我们需要加上 来告知模板引擎,该 html 是安全的,无需再次 escape,直接渲染。

    而这样用起来比较麻烦,而且容易遗忘,所以我们可以封装下:

    • 在渲染时使用自定义的 helper
    1. // {plugin_root}/lib/view.js
    2. const ViewHelper = require('./helper');
    3. module.exports = class MyCustomView {
    4. render(filename, locals) {
    5. locals.helper = new ViewHelper(this.ctx);
    6. // 调用 Nunjucks render
    7. }
    8. }

    具体代码可

    模板和安全息息相关,egg-security 也给模板提供了一些方法,模板引擎可以根据需求使用。

    首先声明对 的依赖:

    1. {
    2. "name": "egg-view-nunjucks",
    3. "eggPlugin": {
    4. "name": "nunjucks",
    5. "dep": [
    6. "security"
    7. ]
    8. }
    9. }

    作为一个高质量的插件,完善的单元测试是必不可少的,我们也提供了很多辅助工具使插件开发者可以无痛的编写测试,具体参见单元测试和中的相关内容。