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:文件監聽

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 產品包壓縮

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插件。。。