7

我有一个使用 Express 和 Jade(现在是 Pug)的 nodejs 应用程序。我想预编译翡翠模板以获得更好的性能。我已经能够使用jade --client将所有 .jade 文件编译为相应的 .js 将翡翠转换为 javascript。

如何在我的应用程序中使用这些 js 文件?我对nodejs / express没有太多经验,但我认为它必须需要更改渲染引擎?我已经阅读了说要使用的官方文档,runtime.js但我找不到任何文档来说明它的使用方式。

4

3 回答 3

10

Jade(现在的 Pug)是一个很棒的模板引擎,但是视图的编译消耗了很多资源。玉很。当然,您可以在生产环境中使用 express 的“缓存视图”功能来缓存已编译的视图,但已编译的视图存储在内存中会消耗大量资源。感谢Jade,我开发的最新的express app 800多毫秒响应了第一个请求,所以我不想改变模板引擎,所以我和你一样,决定编译Jade关于我的开发的意见环境并部署这些文件而不是原始视图。

为了使用编译后的视图,这些.js文件是由一个名为的函数组成的文件template,你需要使用jade运行时。运行时生成属性值并执行其他操作,例如转义值。该template函数接受一个用于动态数据的参数。

由于这些函数是为客户端编译的,编译后的视图依赖于一个全局的翡翠运行时(即window.jade)。在 node.js 中,您可以填充GLOBAL对象,即GLOBAL.jade = require('jade/lib/runtime'),但这不是一个好主意。我决定修改编译后的函数:

  1. 我们可以require使用..jsmodule.exports
  2. 该函数接受第二个参数,即玉运行时。

以下代码片段使用gulp,gulp-jadegulp-replacea 中的节点模块.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'));

现在响应应用程序启动时的第一个请求对我来说需要 7 毫秒。请注意,require对于不存在的文件会引发错误,因此您可以考虑使用try/catchor promises 来处理可能的异常。

于 2016-06-14T20:55:30.643 回答
1

您可以使用jade-runtime 模块(非官方)。当你这样做时require("jade-runtime"),它似乎向 GLOBAL 对象添加了一个“jade”对象,所以它可能只是这样工作。

对我有用的是将以下代码添加到包含(客户端模式)编译模板函数的文件中。

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)某处做并重用它。事实上,如果 express 没有缓存已编译的模板本身,我会感到惊讶res.render(templateName, vars)。如果没有,那就太浪费了。但是我没有快递的经验。您是否检查过 Express 渲染功能的作用?

于 2013-05-04T17:18:02.197 回答
0

您可以尝试使用非常易于使用的 requirejs 模块。在您的服务器端代码中,您可以在一个文件夹中预编译您的翡翠文件,然后从客户端您可以调用 require 函数来运行您的预编译模板,如下所示:

require(['<template_name>'], function (parse) {
                document.getElementById(<div_id).innerHTML = parse({
                    locals: <data_to_be_passed>
                })
            })
于 2013-05-04T16:49:57.917 回答