這兩天對seajs模塊進行打包合併時,推薦的concat工具不是很好用,不知道是不是我們的使用姿勢有問題,無法合併更深層級依賴的模塊,所以只能自己寫個合併工具來進行transport後的合併:
/** * @fileoverview * @author Random | http://weibo.com/random * @date 2013-11-27 */ var fs=require("fs"); var fileList=[]; var readed={}; var conf = { path : "../build/transport/", //基礎目錄,模塊文件地址依賴於該目錄 src : "_html/demo/index.js", //入口文件地址 dist : "../build/" //合併生成後的文件存放目錄 }; var re=new RegExp("(\\.[a-z]+)$","i"); function getModuleList(fileStream){ var modules = []; var p = new RegExp("require\\([\"']([^\\)]+)[\"']\\)","img"); var r = fileStream.match(p); var i; if(r){ i=r.length; while(i--){ r[i].match(p) && modules.push(RegExp.$1); } } return modules; } function getFile(moduleName){ var stream=""; var file; !(/\.js$/.test(moduleName)) && (moduleName+=".js"); file= conf.path + moduleName; if(fs.existsSync(file)){ stream = fs.readFileSync(file, "utf-8"); }else{ console.log("file not found:" + file); } return stream; } function find(file){ var fstr; var mds; var i; var realFile; fstr = getFile(file); if(fstr && !readed[file]){ fileList.push(fstr); readed[file] = 1; console.log(file); mds = getModuleList(fstr); if(mds.length){ i = mds.length; while(i--){ find(mds[i]); } } } } function getFileName(){ var name; var arr = conf.src.split("/"); var src = arr.pop(); if(src.match(re)){ name = conf.dist + src.replace(re, "-all"+RegExp.$1); }else{ name = conf.dist + src + "-all"; } return name; } find(conf.src); if(fileList.length){ if(!fs.writeFileSync(getFileName(), fileList.join("\n") ,"utf-8")){ console.log("\nsuccessful"); } }
大家可以從 npm 直接安裝:
npm install grunt-cmd-combi
該工具可以從入口文件中開始查詢所有層級的模塊依賴,並最後合併這些文件到最終的大文件中。目前只支持js,而且用正則匹配的模塊地址,後續有空再完善吧……