一个周末掌握IT前沿技术之node.js篇<三>:Node.js与服务端模板引擎





“变化”是永恒不变的。你并不能为“变化”做规划,但你可以提前为此做准备。真正的力量是放弃任何概念,振作起来面对改变。你能够适应你当前正处于的环境,这是最关键的。换句话说,接受变化总会发生这个实事,你要不停地学习。

《Node.js发展简史》
2009年2月,Ryan Dahl在博客上宣布准备基于V8创建一个轻量级的Web服务器并提供一套库。
2009年5月,Ryan Dahl在GitHub上发布了最初版本的部分Node.js包,随后几个月里,有人开始使用Node.js开发应用。
2009年11月和2010年4月,两届JSConf大会都安排了Node.js的讲座。
2010年年底,Node.js获得云计算服务商Joyent资助,创始人Ryan Dahl加入Joyent全职负责Node.js的发展。
2011年7月,Node.js在微软的支持下发布Windows版本。

在web2.0的时代,也就是Facebook的时代,为了满足动态网页的需求,出现了一些优秀的HTML内嵌式的语言(php/jsp/asp)。什么是HTML内嵌式语言,读懂下面这段php代码就能明白。

index.php如下:

<html>
<body>

<?php
$arr=array("one", "two", "three");

foreach ($arr as $value)
{
  echo "Value: " . $value . "<br />";
}
?>

</body>
</html>

在所有HTML内嵌式语言中,在1995年出现的php,无论是在性能、语言特性,还是开发效率、运维成本等方面,都是最优秀的。这也就是php是web2.0的时代最流行的web开发语言的原因。用PHP做出的动态页面与其他的编程语言相比,PHP是将程序嵌入到HTML文档中去执行,执行效率比完全生成HTML标记的CGI要高许多;PHP还可以执行编译后代码,编译可以达到加密和优化代码运行,使代码运行更快。大家对它是这么赞扬的:

“如果你希望在软件设计上做出明智的决定,PHP是你开发Web应用程序的最佳选择。顺便说一下,如果你确信要使用PHP来开发下一个Web应用,请试一试CodeIgniter。它是一个轻量级的,普通的,超级快的PHP框架。对于CodeIgniter,我是个粉丝。”

Facebook的前端也是由php构建,并使用HipHop技术,把PHP转成C++并用g++编译,提高服务器的性能。推荐阅读下面两篇文章,它们代表着web2.0时代web技术的最高水平:
《揭秘Facebook的系统架构》
《Tumblr网站架构:15 Billion Page Views a Month 》

HTML内嵌式语言,是一种服务器模板语言。要掌握它们之中的任意一种,都需要几本书的学习内容,掌握它们的一些概念和框架,比方说,tomcat,Servlet,Zend,.net,com组件,ActiveX组件,连接池等等。如果你没听过上面这些名词,没关系。因为随着技术的发展,我们可以用更好的方法来实现它们可以实现的功能。那么Node.js如何输出动态网页呢?接下来我们就去学习。


三. Node.js与 服务器模板语言


什么是动态网页呢?顾名思义,动态网页就是网页的内容不是一成不变的,它会根据用户、时间、内容以及用户操作的不同,呈现不同的网页显示。技术上我们可以这么理解,将一堆数据扔给一段逻辑,这段逻辑会依据这些数据生成相应的HTML编码,再显示在用户网页上。这段HTML编码会根据数据的变化而变化,这就是动态网页。而这段逻辑代码就是模板语言。JavaScript因为语言特性强大,200行代码就可以实现一个优秀的模板引擎。所以JavaScript模板语言只有一个特征那就是:混乱。我们可能听说过一些有名的JavaScript模板语言:jade、jQueryTemplate、doTtemplate、ejs还有很多。下面这个链接是一些Javascript模板引擎性能对比在线测试:
《JavaScript template language shootoff》
你有两块手表时,就不知道时间了,何况是十块八块。我们只挑选一种来学习。


3.1 Node.js与nTenjin

nTenjin是基于jsTenjin修改的高性能的支持Node.js的模板解析引擎 (A template engine base on jsTenjin’s and more fase and support Node.js )
项目主页:《nTenjin》
高性能,清晰的模板结构,强大的模板功能是nTenjin的3个优点。nTenjin的源代码清晰,阅读代码可以发现,它的高性能正是来自于项目主页上所说的两点原因:1.将模板语言剪辑翻译,再调用“new Function(‘it’, buf);”,生成JavaScript函数;2.生成JavaScript函数在被调用时,使用“String += str”拼接字符串,输出应的HTML编码。
我们看下面这一段nTenjin模板:

<div>
	<h1 class='header'>#{ it.header }</h1>
    <h2 class='header2'>#{ it.header2 }</h2>
    <h3 class='header3'>#{ it.header3 }</h3>
	<h4 class='header4'>#{ it.header4 }</h4>
	<h5 class='header5'>#{ it.header5 }</h5>
	<h6 class='header6'>#{ it.header6 }</h6>
    <ul class='list'>
		<?js for (var i = 0, l = it.list.length; i < l; i++) { ?>
			<li class='item'>#{ it.list[i] }</li>
        <?js } ?>
	</ul>
</div>

其中“#{}包”含就是变量名,“<?js >”标签包含的就是模板逻辑,会在模板编译的时候导入到生成的JavaScript函数中。
在Node.js中,安装tenjin:

C:\>cd "Program Files\nodejs"
C:\Program Files\nodejs>npm install tenjin

我们来分析下面这个例程:
例程4:
demo4.js如下:

/**
 * Date: 12-3-24
 * 演示程序4
 * 说明: 使用服务端模板nTenjin
 */
var http = require("http");
var tenjin = require('tenjin');

var i = 1;

http.createServer(
	function (request, response) {

	response.writeHead(200, {
		"Content-Type" : "text/html; charset=UTF-8"
	});

	response.write("欢迎您第" + i + "次访问服务器!<br>Welcome!<br>");

	testTenjin(response);
	i++;
	console.log("服务器访问被访问次数: i = " + i);
	response.end();

}).listen(80);

var sharedVariables = {
	header : "Header",
	header2 : "Header2",
	header3 : "Header3",
	header4 : "Header4",
	header5 : "Header5",
	header6 : "Header6",
	list : ['1', '2', '3', '4', '5', '我是6', '7', '8', '9', ' 你好10'],
	o : {
		a : ['我是1啊', {
				b : {
					p : '我是p'
				}
			}, '3', '4', '5', '6', '7', '8', '9', ' 你好10']
	}
};

function testTenjin(response) {
    //第一个case,nTenjin最简单的应用。
	var result1 = tenjin.render('Hello #{it.name}!', {
			name : 'nTenjin'
		});
	console.log("result1是" + result1);//log显示“result1是Hello nTenjin!”
    //第二个case,nTenjin编译html模板。
	var nTenjinTemplate = "<div><h1 class='header'>#{ it.header }</h1><h2 class='header2'>#{ it.header2 }</h2><h3 class='header3'>#{ it.header3 }</h3><h4 class='header4'>#{ it.header4 }</h4><h5 class='header5'>#{ it.header5 }</h5><h6 class='header6'>#{ it.header6 }</h6><ul class='list'><?js for (var i = 0, l = it.list.length; i < l; i++) { ?><li class='item'>#{ it.list[i] }</li><?js } ?></ul></div>";
	var convertednTenjinTemplate = new tenjin.Template();
	convertednTenjinTemplate.convert(nTenjinTemplate);//编译html模板, 生成JavaScript函数
	var result2 = '';
	for (var i = 0; i < 1000; i++) {
		result2 = convertednTenjinTemplate.render(sharedVariables);//根据数据sharedVariables,生成html编码
		sharedVariables.o.a[1].b.q += "+" + i + "+";
	}

	response.write(result2);//输出网页内容
	console.log("result2是" + result2);
	console.log("sharedVariables.o.a[1].b.q" + sharedVariables.o.a[1].b.q);

}
console.log("服务器开启");

别忘了在Run/Debug Configuration中,加入环境变量:“NODE_PATH=C:\Program Files\nodejs\node_modules”。否则webstorm会提示错误找不到模块。例程4的运行结果如下图所示。可以看到sharedVariables的数据,已根据模板的要求显示在了网页上。


3.2 使用nTenjin输出动态轻博客内容

我们可以使用nTenjin输出动态轻博客内容,网页框架、图片、css的拔取方法,只要用熟了chrome浏览器,都非常容易。下面只介绍例程的重点部分,所有例程的源代码都会给出。
例程5:
使用nTenjin网页模板的content.html的部分内容如下:

<!-- 省去很多内容 -->
<div class="feed-list" id="feed-list">
	<?js for (var i = 0, l = it.length; i < l; i++) { ?>
		<!-- 省去很多内容 -->
		<div class="feed-txt-full rich-content">
			<div class="feed-txt-summary">
				<p>#{ it[i] }</p>
			</div>
		</div>
		<!-- 省去很多内容 -->
	</div>
	<?js } ?>
</div>
<!-- 省去很多内容 -->

将content.html保存在demo5文件夹下,demo5.js将会读取该模板,输出结果。
demo5.js如下:

/**
 * Date: 12-3-24
 * 演示程序5
 * 说明: 使用服务端模板nTenjin输出动态轻博客内容
 */
var http = require("http");
var tenjin = require('tenjin');
var fs = require('fs');

var htmlTemplete = {
    html:{},
    loadTemplete:function () {
        this.html['content']={};
        this.html['content'].string= fs.readFileSync('./demo5/content.html', encoding = 'utf8');
        this.html['content'].template = new tenjin.Template();
        this.html['content'].template.convert(this.html['content'].string);//我们需要在初始化时编译html模板, 生成JavaScript函数,而不是每次访问调用模板时编译一遍。
    }
};
var i = 1;
htmlTemplete.loadTemplete();

http.createServer(
    function (request, response) {

        response.writeHead(200, {
            "Content-Type":"text/html; charset=UTF-8"
        });

        testTenjin(response);
        i++;
        console.log("服务器访问被访问次数: i = " + i);
        response.end();

    }).listen(8080);

var articles = ["这是第一篇文章", "这是第二篇文章", "这是第3篇文章"];
function testTenjin(response) {

    var result = htmlTemplete.html['content'].template.render(articles);//调用模板,输出结果
    response.write(result);
    response.write(result);
}
console.log("服务器开启");

例程5的运行结果如下图所示。js数组articles,对应着每一条记录。

本文目录:《一个周末掌握IT前沿技术之node.js篇》
1.《Node.js与javascript》
2.《Node.js与redis》
3.《Node.js与服务端模板引擎》
4.《Node.js与Restful API》
5.《Node.js与Nginx》
6.《Node.js与客户端模板引擎》
7.《Node.js与HBase》
文本粗陋,欢迎斧正!欢迎投稿!原创文章,转载请链接。
联系邮箱:(it.Web.technical#gmail.com)
IT技术精研院
 

Leave a Reply

无觅相关文章插件,快速提升流量