Midway 服务端模板渲染指南:基于 @midwayjs/view 的 EJS 与 Nunjucks 组件集成实战
后端微服务云原生【免费下载链接】midway A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 项目地址https://gitcode.com/gh_mirrors/mi/midway点击查看免费下载导读本文围绕 Midway 2.x 的官方模板渲染扩展组件midwayjs/view及其两个服务端模板引擎实现midwayjs/view-ejs与midwayjs/view-nunjucks展开。组件用于在 Midway 体系内以服务端渲染SSR方式渲染 ejs、nunjucks 模板先介绍组件的安装、引入与view配置项含默认值再完整演示两种模板引擎从「建目录、写模板、Controller 渲染」到「自定义 Nunjucks filter」的落地过程最后结合源码讲解引擎选择链路、全局 locals 注入、视图目录解析等底层机制并给出在 eggmidwayjs/web场景下关闭 egg-view 的注意事项。读完本文你将能在一个 Midway 2.x 应用中独立接入服务端模板渲染并排查常见报错。组件定位一个 view 框架 两套引擎midwayjs/view是 Midway 的视图框架基础包负责视图目录管理、引擎注册、模板路径解析与渲染上下文注入midwayjs/view-ejs与midwayjs/view-nunjucks则是分别基于 ejs 与 nunjucks 的引擎实现。三者相互配合的调用链在源码中非常清晰midwayjs/view的 configuration.ts 在onReady阶段通过Object.defineProperties为 koa / egg / faas 应用的app.context注入了render、renderView、renderString三个方法midwayjs/view-ejs的 configuration.ts 在onReady中调用viewManager.use(ejs, EjsView)注册名为ejs的引擎midwayjs/view-nunjucks同理注册nunjucks引擎并在 engine.ts 中封装 NunjucksEnvironment额外暴露addFilter、addGlobal、getFilter等方法。因此无论使用哪种引擎引入对应组件后Controller 中都统一通过ctx.render/ctx.renderString/ctx.renderView渲染视图具体引擎由配置中的mapping与defaultViewEngine决定。使用 EJS安装依赖在应用根目录安装对应模板引擎组件$ npm i midwayjs/view-ejs2 --save当前文档对应 Midway 2.x 版本安装时指定2标签可固定大版本若使用 Midway 3.x 及以上请按实际版本选择。引入组件在src/configuration.ts中导入组件并放入importsimport { Configuration } from midwayjs/decorator; import * as view from midwayjs/view-ejs; import { join } from path; Configuration({ imports: [ view, // 导入 ejs 组件 ], importConfigs: [join(__dirname, config)], }) export class ContainerLifeCycle {}组件内部会通过imports: [View]自动依赖midwayjs/view见 view-ejs/src/configuration.ts无需手动重复引入基础包。配置在src/config/config.default.ts中声明view配置把.ejs后缀映射到ejs引擎并设置默认引擎// src/config/config.default.ts export const view { defaultViewEngine: ejs, mapping: { .ejs: ejs, }, }; // ejs config export const ejs {};这里export const ejs {}是为了给midwayjs/view-ejs的引擎配置占位。该组件默认配置config.default.ts如下可按需覆盖配置项默认值说明root${appDir}/viewejs 文件根目录cachetrue编译后的函数会被缓存仅在通过ctx.render渲染时生效debugfalse输出生成的函数体便于调试compileDebugtrue设为false时不编译调试插桩delimiternull用于尖括号开/闭合的界定符字符strictfalse为true时生成的函数处于严格模式在 EjsView.render 的实现中这些配置会与options合并后透传给ejs.renderFile同时该实现还支持config.layout布局页能力——当配置了layout时先渲染模板内容写入locals.body再渲染布局页这在服务端渲染中常用。使用默认的 view 目录为${appRoot}/view在其中创建一个hello.ejs文件。目录结构如下➜ my_midway_app tree . ├── src │ └── controller ## Controller 目录 │ └── home.ts ├── view ## 模板目录 │ └── hello.ejs ├── test ├── package.json └── tsconfig.json在模板里写一些 ejs 格式的内容%-- view/hello.ejs --% hello % data %在 Controller 中渲染import { Inject, Provide } from midwayjs/decorator; import { Context } from midwayjs/koa; Provide() Controller(/) export class HomeController { Inject() ctx: Context; Get(/) async render() { await this.ctx.render(hello.ejs, { data: world, }); } }访问首页后页面会输出hello world。ctx.render由 view 组件注入packages/view/src/configuration.ts内部会获取当前请求上下文中的ContextView执行渲染并把结果写入this.body若只想拿到渲染结果字符串而不写入 body可使用ctx.renderView或ctx.renderString。使用 Nunjucks和 ejs 类似引入对应组件即可。1、安装依赖$ npm i midwayjs/view-nunjucks --save2、引入组件在src/configuration.ts中导入import { Configuration } from midwayjs/decorator; import * as view from midwayjs/view-nunjucks; import { join } from path; Configuration({ imports: [ view, // 导入 nunjucks 组件 ], importConfigs: [join(__dirname, config)], }) export class ContainerLifeCycle {}3、增加 nunjucks 配置在src/config/config.default.ts中增加 nunjucks 的配置默认使用 nunjucks// src/config/config.default.ts export const view { defaultViewEngine: nunjucks, mapping: { .nj: nunjucks, }, };nunjucks 引擎在启动时engine.ts会根据view.root创建FileSystemLoader并把config.nunjucks.noCache、throwOnUndefined、trimBlocks、lstripBlocks、tags、autoescape等选项透传给Environment构造器其中noCache !config.cache即 nunjucks 的cache默认值相关配置可通过组件配置覆盖。4、在 view 目录增加模板%-- view/test.nj --% hi, {{ user }}注意原文档示例文件名写作test.ejs但配置的映射是.nj后缀实际渲染调用ctx.render(test.nj, ...)时以.nj文件为准。文件名后缀需与mapping中配置的后缀一致否则无法匹配到引擎。在 Controller 中渲染import { Inject, Provide } from midwayjs/decorator; import { Context } from midwayjs/koa; Provide() Controller(/) export class HomeController { Inject() ctx: Context; Get(/) async render() { await ctx.render(test.nj, { user: midway }); } }访问后会输出hi, midway。自定义 filter如果有自定义 filter 的需求可以在入口Configuration 类处增加。下面增加了一个名为hello的 filterimport { App, Configuration, Inject } from midwayjs/decorator; import * as view from midwayjs/view-nunjucks; import { join } from path; Configuration({ imports: [view], importConfigs: [join(__dirname, config)], }) export class AutoConfiguration { App() app; Inject() env: view.NunjucksEnvironment; async onReady() { this.env.addFilter(hello, (str) { return hi, str; }); } }NunjucksEnvironment在 engine.ts 中以单例Scope(ScopeEnum.Singleton)形式提供addFilter直接透传到底层nunjucksEnvironment.addFilter。在模板里可以使用{{ name | hello }}然后渲染// controller // ... await ctx.render(test.nj, { name: midway });同样会输出hi, midway。引擎选择与视图解析的底层原理理解「为什么这样配置就能渲染」有助于排查问题。核心链路位于 packages/view/src/contextView.ts路径解析ViewManager.resolve(name)在配置的root默认${appDir}/view中查找文件支持自动补全defaultExtension默认为.html见 config.default.ts。若渲染时省略后缀例如ctx.render(hello)会尝试hello与hello.html引擎匹配先取options.viewEngine未指定时按文件扩展名查mapping仍无结果则回退到defaultViewEngine渲染从ViewManager中取出注册的引擎类通过当前请求的requestContext获取实例并把全局 locals、ctx、ctx.request、ctx.locals与本次渲染的 locals 合并后传入引擎的render。ViewManagerviewManager.ts在初始化时会收集view.rootDir与view.root配置中的有效路径作为视图根目录并将view.mapping写入扩展名映射表extMap同时提供addLocals方法注册全局变量可让所有模板共享数据测试用例可见test/index.test.ts。注意事项egg 场景需关闭 egg-view如需在 eggmidwayjs/web场景下使用本组件请在src/config/plugin.ts即原文档中提到的plugint.ts中关闭 view 及其相关插件import { EggPlugin } from egg; export default { // ... view: false, } as EggPlugin;否则会出现类似下面的错误TypeError: Cannot set property view of #EggApplication which has only a getter原因在于 egg 框架自身也提供了view能力egg-view它会预先在app.context上定义只带 getter 的view属性而midwayjs/view注入的ctx.render等能力与 egg 的view属性存在冲突因此在midwayjs/web应用中必须显式关闭 egg 的 view 插件避免属性冲突。在纯 koa 应用midwayjs/koa或 faas 场景下则无需处理。小结服务端模板渲染在 Midway 2.x 中的接入路径为安装midwayjs/view-ejs或midwayjs/view-nunjucks→ 在configuration.ts的imports中引入 → 在config.default.ts配置view.mapping与view.defaultViewEngine→ 在${appRoot}/view目录放置模板 → 在 Controller 中调用ctx.renderejs 与 nunjucks 的差异集中在模板语法与引擎配置如delimiter、autoescape框架层的view配置、目录约定与渲染方法完全一致自定义能力方面nunjucks 提供了addFilter/addGlobalejs 侧则支持layout布局页等配置egg 场景必须关闭 egg 自带的 view 插件防止ctx.view属性冲突报错。赞分享后端微服务云原生【免费下载链接】midway A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 项目地址https://gitcode.com/gh_mirrors/mi/midway点击查看免费下载相关推荐Midway 模板渲染实战基于 midwayjs/view 接入 ejs / nunjucks 并自定义渲染引擎Midway 模板渲染实战基于 midwayjs/view 接入 ejs / nunjucks 并自定义渲染引擎 本文围绕 Midway 框架的模板渲染组件后端微服务云原生Midway 模板渲染View组件完全指南在 Koa/Faas/Web 中集成 EJS 与 NunjucksMidway 模板渲染View组件完全指南在 Koa/Faas/Web 中集成 EJS 与 Nunjucks 本篇技术指南聚焦 midway 框架的 Vi后端微服务云原生Midway 模板渲染组件实战在 Koa/Faas/Web 应用中使用 ejs 与 Nunjucks 服务端渲染Midway 模板渲染组件实战在 Koa/Faas/Web 应用中使用 ejs 与 Nunjucks 服务端渲染 Midway 内置了统一的模板渲染View后端微服务云原生上一篇Flexbox Froggy用户反馈从1000评论中提炼的改进建议下一篇5大实战技巧深度解锁MPC Video Renderer的RTX HDR渲染能力创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考