一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

HTML模版引擎整合:在Express框架里配置多种HTML模版引擎共存的方法

时间:2026-07-09 11:25:57 编辑:袖梨 来源:一聚教程网

Express需同时配置app.set('view engine','ext')与app.engine('ext',handler)才能渲染对应后缀文件;多引擎共存须用不同扩展名或手动调用引擎,避免app.engine覆盖。

Express 本身不内置 HTML 模板引擎,必须显式配置 app.engine() 才能支持 .html 后缀文件渲染;多个 HTML 引擎共存是可行的,但不能靠简单叠加 app.set('view engine', ...) 实现——它只接受单个字符串值,无法“切换”引擎。

为什么 app.set('view engine', 'html') 不等于“用了 HTML 引擎”

这个设置只是告诉 Express:当调用 res.render('index') 时,默认去找 index.html(而不是 index.ejsindex.pug)。但它不负责解析该文件——解析逻辑由 app.engine('html', ...) 绑定的回调决定。如果没配 app.engine('html', ...),直接访问会报错 Error: Failed to lookup view "index" in views directory 或更隐晦的 TypeError: callback is not a function

  • app.set('view engine', 'html') 是“找文件名”的约定
  • app.engine('html', require('ejs').__express) 才是“怎么读这个文件”的实现
  • 二者缺一不可,且 app.engine 的第一个参数(扩展名)必须和 view engine 值一致,否则匹配失效

如何让 EJS 和 art-template 同时处理 .html 文件

不能直接注册两个 app.engine('html', ...)——后注册的会覆盖前一个。正确做法是用文件扩展名区分,比如让 EJS 处理 .ejs.html,art-template 处理 .art.html

  • 安装两个引擎:npm install ejs art-template express-art-template
  • 分别绑定不同扩展名:
    app.engine('ejs.html', require('ejs').__express);app.engine('art.html', require('express-art-template'));
  • 设置默认引擎为其中一个(如 app.set('view engine', 'ejs.html')),或渲染时显式传扩展名:res.render('page.ejs.html', data)res.render('page.art.html', data)
  • 确保 views 目录下对应文件存在,例如 views/page.ejs.htmlviews/page.art.html

consolidate 统一接入多个引擎的坑

consolidate 能简化多引擎接入,但它对 .html 后缀的支持有陷阱:

立即学习“前端免费学习笔记(深入)”;

  • 它内部把 consolidate.ejs 当作函数调用,但 EJS 的 __express 方法依赖 filename 参数,而 consolidate 在某些版本中可能未透传该参数,导致 includepartial 失效
  • 若同时注册 consolidate.ejsconsolidate.handlebars 到同一扩展名(如 html),仍会发生覆盖
  • 推荐只用 consolidate 接入非主流引擎(如 swigdot),主流引擎(EJS/Pug/Handlebars)优先走原生 app.engine 绑定

真正“共存”的关键:路由级手动选择引擎

最可控的方式不是靠扩展名,而是绕过 res.render() 自动查找机制,在路由里手动调用引擎函数:

  • 引入两个引擎:const ejs = require('ejs')const template = require('art-template')
  • 读取模板字符串:const html1 = fs.readFileSync('./views/page1.html', 'utf8')
  • 分别渲染:
    const result1 = ejs.render(html1, data);const result2 = template.render('./views/page2.html', data);
  • res.send(result1)res.type('html').send(...) 输出
  • 这样完全脱离 Express 的视图系统,自由度最高,也最易调试——但失去 layoutpartials 等框架级功能

多引擎共存不是配置开关,而是路径、扩展名、调用时机三者的组合决策;最容易被忽略的是 app.engine 的覆盖行为——它不报错,只静默替换,出问题时往往以为是模板语法错,其实根本没走到你期望的那个引擎。

热门栏目