[英]How to render precompiled Jade (Pug) templates in a Node.js Express app?
我有一个使用Express和Jade(现在是Pug)的nodejs应用程序。 我想预编译jade模板以获得更好的性能。 我已经能够使用jade --client
将jade转换为javascript以将所有.jade文件编译为相应的.js。
如何在我的应用程序中使用这些js文件? 我对nodejs / express没有太多经验,但我认为它必须要求更改渲染引擎? 我已经阅读了使用runtime.js
的官方文档,但我找不到任何文档,因为它是如何使用的。
Jade(现在的Pug)是一个很棒的模板引擎,但是视图的编译消耗了大量的资源。 玉很慢 。 当然,您可以使用快速生成的“缓存视图”功能来缓存已编译的视图,但编译的视图存储在可能占用大量资源的内存中。 感谢Jade,我开发的最新快速应用程序响应了超过800毫秒的第一个请求,因此我不想更改模板引擎,我和你一样,决定在我的开发中编译Jade视图环境并部署这些文件而不是原始视图。
为了使用由名为template
的函数组成的.js
文件的编译视图,您需要使用jade 运行时 。 运行时生成属性值并执行其他内容,例如转义值。 template
函数接受一个用于动态数据的参数。
由于这些函数是为客户端编译的,因此编译的视图依赖于全局jade运行时(即window.jade
)。 在node.js中,您可以填充GLOBAL
对象,即GLOBAL.jade = require('jade/lib/runtime')
但这不是一个好主意。 我决定修改编译的函数,所以:
module.exports
来require
编译视图( .js
文件)。 下面的代码段使用gulp
, gulp-jade
和gulp-replace
中的一个节点的模块.gulpfile
:
gulp.task('compile-jade', () => {
// get all the jade files and compile them for client
return gulp.src([
'../views/**/*.jade'
]).pipe(jade({
client: true
}))
// replace the function definition
.pipe(replace('function template(locals)', 'module.exports = function(locals, jade)'))
.pipe(gulp.dest('../views_js') );
});
现在我们已经更改了函数声明,我们可以加载编译文件( .js
文件)而不是.jade
文件。 但还有另一个问题。 使用这些文件没有预先制作的模板引擎(据我所知)。 所以我们需要定义一个新的引擎。 这很简单:
let jade = require('jade/lib/runtime');
app.engine('js', function (filePath, options, callback) { // define the template engine
let data = require(filePath)(options, jade);
callback(null, data);
});
现在我们可以在express中更改视图相关设置:
app.set('view engine', 'js');
app.set('views', path.join(__dirname, 'views_js'));
现在响应启动应用程序的第一个请求需要7ms。 请注意,对于不存在的文件, require
抛出错误,因此您可以考虑使用try/catch
或promises来处理可能的异常。
您可以使用jade-runtime模块(非官方)。 当你require("jade-runtime")
它似乎将一个“jade”对象添加到GLOBAL对象中,因此它可能就像那样工作。
对我有用的是将以下代码添加到包含(客户端模式)编译模板函数的文件中。
jade = require("jade-runtime").runtime
module.exports =
请参阅https://github.com/meryn/make-document-html及其Makefile以查看其工作情况(已编译的,可获取的模板函数最终在lib / template.js中)。 但它也可以在Node.js本身完成。
我需要补充一点,除非你想要阻止Jade依赖(就像我一样),否则没有必要使用预编译的模板文件来获得预编译的好处。 你可以在某处做templateFn = jade.compile(templateCode)
用它。 事实上,当你执行res.render(templateName, vars)
时,如果express不缓存已编译的模板本身,我会感到惊讶。 如果没有,那将是浪费。 但我没有快递经验。 你有没有检查一下Express渲染功能呢?
你可以尝试一下非常好用的requirejs模块。 在您的服务器端代码中,您可以在文件夹中预先编译您的jade文件,然后从客户端,您可以调用require函数以运行预编译的模板,如下所示:
require(['<template_name>'], function (parse) {
document.getElementById(<div_id).innerHTML = parse({
locals: <data_to_be_passed>
})
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.