簡體   English   中英

如何在Node.js Express應用程序中渲染預編譯的Jade(Pug)模板?

[英]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')但這不是一個好主意。 我決定修改編譯的函數,所以:

  1. 我們可以通過使用module.exportsrequire編譯視圖( .js文件)。
  2. 該函數接受第二個參數,即jade運行時。

下面的代碼段使用gulpgulp-jadegulp-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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM