在express 3.x 中使用doT.js
发布于 1年前 作者 albertshaw 1405 次浏览 最后一次编辑是 5个月前 来自 分享

看见有不少朋友在坛子里问如何在express中使用doT.js,刚好我前不久用过,把我那会儿写的文章转过来吧。
本文github原文地址:如何在express 3.x 中使用doT.js

如何在express 3.x 中使用doT.js

起因是我的个人博客模板选择问题,期间纠结了很久,然后在知乎搜到了答案,见:如何选择 EJS 和 Jade? 非常感谢其中江平Lahm的回答,让我知道了doT.js各模板引擎的表现. 再加上看完例子后也喜欢上了doT的用法,于是就这么掉进了doT的坑里…

个人博客框架选用的Express,那么首先自然是了解Express里面如何使用doT了,搜到的第一篇就是如何在express使用doT模板引擎,看完一乐,原来这篇文章的诞生也是因为发现doT最快啊,都两年多了,doT依然跑得最快…

屁颠屁颠跑去依葫芦画瓢,然后,就傻了,互联网可不会原地等你两年。Express升级到3.x了!!!

这里变化挺大的,register没了,出了个engine,用法当然不同了。还好stackoverflow靠谱,找到了这个答案

是的,就是使用express-dot

$ npm install express-dot

使用也很方便

// load express doT
var doT = require('express-dot');

// (optional) set globals any thing you want to be exposed by this in {{= }} and in def {{# }}
doT.setGlobals({ ... });

  // doT engine
  app.set('view engine', 'dot' );
  app.engine('dot', doT.__express );

到这里,就终于可以用了,但是完了么?

不算完…

express-dot虽然能用了,但是依然有几个不爽的地方。

  • def需要在global settings中传入,引入外部文件的def不那么方便。
  • 不能服务器启动时预编译
  • 要么不做cache,做了cache之后要想看到模板变化就只能重启服务器了。

怎么办?

嘿咻嘿咻去看文档,看源码吧。

doT支持引入外部模块文件是在其内部有个方法可以在编译时将碎片模块注入主模块留作解析。使用时只要在主模块中定义def,比如:

{{#def.topnav}}

然后在调用templete方法时将def传入如:

def={
 topnav:"<div>blahblahblah...</div>"
 //这里可以是一个loadfile方法,返回string就ok
}
dot.templete(mainDot,settings,def)

并且服务器启动时的预编译,dot也是支持的,dot exports 了一个process方法. 使用如下

var doTemps = require('dot').process({
 path : "./views"
});

传入个文件夹路径,这样就可以将该views文件夹中dot,def,jst文件编译好,并返回一个对象doTemps,当调用res.render("filename",data)时,将其指向调用doTemps[filename]就能完成解析调用callback。

var path = require('path');
var settings = require('./configs/settings').config;
var dot = require('dot');
var fs = require('fs');
var temppath = "./views";
var doTemps = dot.process({
 path : temppath
});

function spyTemps(){
    fs.watch(temppath, function(event, filename){
        this.close();
        doTemps = dot.process({
            path : temppath
        });
        spyTemps();
    });
}

spyTemps();

function getFileName(filename) {
 var slashIndex = filename.lastIndexOf("\\"), dotIndex = filename
   .lastIndexOf(".");
 return filename.substring(slashIndex + 1, dotIndex);
}

function _renderFile(filename, options, cb) {
 var name = getFileName(filename);
 var template = doTemps[name];
 if (template) {
  options.site = settings.site;
  options.env = process.env.NODE_ENV || 'development';
  return cb(null, template(options));
 } else {
  return cb(new Error(name + " is not found!"));
 }
}

exports.__express = function(filename, options, cb) {
 cb = (typeof cb === 'function') ? cb : function() {
 };
 return _renderFile(filename, options, cb);
};

写完大概就这样了, 还加了个文件夹监听spyTemps,当文件有改动时dot重新编译, 偷懒写的, 一个文件的改动都会触发的整个文件夹编译, 哈哈, 先用着,反正dot速度快,以后有空再完善吧.

5 回复

各种模板引擎都有自己的特点吧。。我接触的比较少, 这几个模板引擎 怎么选择比较好呢 ?

随大流jade或者ejs,这样比较稳妥,适合做商业项目。这两者怎么选完全就是看个人口味了, 我喜欢ejs一点,因为我喜欢看上去直观一点的模板。

小众模板适合做自己的东西玩,比如这个doT,号称最快,而且jsperf上的测试也显示确实最快。

express的模板引擎接口一定,模板的学习成本也不高,完全可以自己都看看。 并且现在有些模板支持自定义标签,比如dot,backbone都支持,这样的话,模板迁移的成本也降低了。

@albertshaw 谢谢你给我这么完整的答复。 我选择了ejs。 jade的风格 我暂时还无法接受, 习惯了标签对 html的格式了

doT速度快 肯定在某些方面有用武之地的

express-dot.js 看源码作者根本没有开发完成。 看dot.js没有发现暴露了process方法 另外有个问题,我不想去掉template里面的回车应该怎么做?

express-dot确实还是开发版,所以说只是’能用’了。 如果dot.js你是用npm install dot装载的话你会在你工程的\node_modules\dot下发现index.js文件,process方法在这里面。

不明白你问的不想去掉template里面的回车是什么意思

回到顶部