模块合并小工具
这两天对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,而且用正则匹配的模块地址,后续有空再完善吧……