代码改变世界

利用Node.js本地构建

2013-02-23 23:12  破狼  阅读(3693)  评论(0编辑  收藏  举报

 

                  Node.js是一个基于Google Chrome浏览器v8 javascript执行引擎的异步I/O事件驱动的运行平台。直从2009年诞生开始,已经在业界得到了很多的关注,在这里也必要多说,如果你还不清楚的,请移步到Node官网

在这里我们要讲的是用Node.js来构建本地Build。构建本地Build,我们已经有很多选择,如Ant,Maven,Gradle等。为什么我们还需要Node.js?对于我们的开发中会有一些小的基本自动化构建,如文件的监控(Less编译),javascript的压缩,不稳定集成服务代理,快速的集成反馈,文件的迁移…而对于项目来说我并不像引入太多的技术债, Node.js所使用的javascript是做web项目开发的一门必备技能,javascript作为一门比较容易入门语言,直从第一次接触Node.js,我爱不释手,由于我对Javascript基础,能够快速使用它,并不需要付出更多的学习成本,而且我感觉在服务端和客户端用同一种语言,在能一定代码重用妙不可言。而且Node.js提供了内置的web服务器,简单的文件监听,事件机制等也为做本地Build提供了很好的条件。

1:文件监听

View Code
  1 var fs = require("fs");
  2 
  3 var exec = require('child_process').exec
  4 
  5 var underscore = require("underscore");
  6 
  7 var configs = [
  8 
  9     {file:/.*\.less/g, command:" dotless.Compiler.exe style.less style.css"}
 10 
 11 ];
 12 
 13 var source = "E:\\Project\\xxx\\style";
 14 
 15  
 16 
 17 String.format = function () {
 18 
 19     var s = arguments[0];
 20 
 21     for (var i = 0; i < arguments.length - 1; i++) {
 22 
 23         var reg = new RegExp("\\{" + i + "\\}", "gm");
 24 
 25         s = s.replace(reg, arguments[i + 1]);
 26 
 27     }
 28 
 29  
 30 
 31     return s;
 32 
 33 };
 34 
 35  
 36 
 37 (function (fs, exec, underscore) {
 38 
 39     var readFiles = function (dir, done) {
 40 
 41         var results = [];
 42 
 43         fs.readdir(dir, function (err, list) {
 44 
 45             if (err) return done(err);
 46 
 47             var pending = list.length;
 48 
 49             if (!pending) return done(null, results);
 50 
 51             list.forEach(function (file) {
 52 
 53                 file = dir + '/' + file;
 54 
 55                 fs.stat(file, function (err, stat) {
 56 
 57                     if (stat && stat.isDirectory()) {
 58 
 59                         readFiles(file, function (err, res) {
 60 
 61                             results = results.concat(res);
 62 
 63                             if (!--pending) done(null, results);
 64 
 65                         });
 66 
 67                     } else {
 68 
 69                         results.push(file);
 70 
 71                         if (!--pending) done(null, results);
 72 
 73                     }
 74 
 75                 });
 76 
 77             });
 78 
 79         });
 80 
 81     };
 82 
 83     var start = function (source, configs) {
 84 
 85         var watch = function (error, list) {
 86 
 87             configs.forEach(function (cmd) {
 88 
 89                 var files = underscore.filter(list, function (n) {
 90 
 91                     return n.match(cmd.file);
 92 
 93                 });
 94 
 95                 files.forEach(function (file) {
 96 
 97                     fs.watch(file, function (oper, f) {
 98 
 99                         var changeCommand = String.format(cmd.command, f);
100 
101                         console.log(String.format("{0} changed,command '{1}' execute...", f, changeCommand));
102 
103                         exec(changeCommand, function (err, stdout, stderr) {
104 
105                             console.log(err ? stderr : stdout);
106 
107                         });
108 
109                     });
110 
111                 });
112 
113  
114 
115             });
116 
117         };
118 
119         readFiles(source, watch);
120 
121     };
122 
123     return {start:start};
124 
125 })(fs, exec, underscore).start(source, configs);

在这里提供的示例是Less的编译,虽然Less本也提供了Node的编译工具和watchr监听工具,但是在项目中我会监听Less文件,却只有编译几个固定的Less引导文件。同样我们可以根据不同的文件执行不同的命令实现一些自动化。如:.js文件的同步到测试目录。

2:文件的合并

如果你用jasmine运行你的Javascript测试,你需要吧js文件的测试文件引入到runner head中,我一直很懒,喜欢一键搞定的感觉。利用node.js的模板引擎。

   3:javascript 产品包压缩

View Code
 1 var FILE_ENCODING = 'utf-8';
 2 
 3 function uglify(srcPath, jsMinPath) {
 4 
 5     var uglyfyJS = require('uglify-js'),
 6 
 7        jsp = uglyfyJS.parser,
 8 
 9        pro = uglyfyJS.uglify,
10 
11        ast = jsp.parse( _fs.readFileSync(srcPath, FILE_ENCODING) );
12 
13  
14 
15       ast = pro.ast_mangle(ast);
16 
17       ast = pro.ast_a squeeze(ast);
18 
19       _fs.writeFileSync(jsMinPath, pro.gen_code(ast), FILE_ENCODING);
20 
21     console.log(' '+ jsMinPath +'完成.');
22 
23 }
24 
25 uglify(js/test.js', js/test.min.js');

我们可以尽力发挥自己的想象,如本地Build自动运行,快速集成快速反馈;代理服务器,处理不稳定服务的集成,带来稳定的开发,比如testacluar就是根据node.js能够很容易的构建web服务器,从jstd转过来的javascript test和coverage插件。。。