根据nicEdit 源码组织结构 中所讲的组织方法,和打包注释,其实可以做一个通用的,nicEdit代码风格的模块打包器.
这里用JavaScript实现一个(没有全部完成,有些地方如何做更好,还在考虑中),
对于一个打包器来说,数据的来源我并不考虑,因为这和使用方法有关,你可以从后台程序输出,也可以通过web服务器支持目录列表自动获取,就是因为方法很多,所以这才不是打包器考虑的内容.
/**
* nicEdit 风格 模块打包器说明
*/
var modulePacker={
/**
* 初始化,输入是一个nicEdit 风格的 src 目录结构的对象,最终js文件直接附加原始文件文本
* 例如:
{
nicCore:{
nicCore.js:'source code',
bkLib.js:'source code'
},
nicCode:{
nicCode.js:'source code'
}
}
* 生成一个按模块分的依赖关系对象 this.Dep
* 生成一个按依赖关系的模块打包次序数组 this.Order
*/
init:function(src,license){
function find(str){
var s = module.indexOf(str);
if (s<0) return false;
s=s+str.length;
var e = module.indexOf('\n',s);
if (e<0) return false;
return module.slice(s,e).split(',');
}
this.Src=src;
this.Dep={};
this.Pk={};
this.Remove={};
for (var i in src) {
if (typeof src[i]=='string' || typeof src[i][i+'.js']!='string') continue;
this.Dep[i]={};
var module = src[i][i+'.js'];
var dep=find('@requires:');//分析依赖请求
if (dep)
for (var j = 0; j < dep.length; j++) {
dep[j]=(dep[j] || "").replace( /^\s+|\s+$/g, "" );
this.Dep[i][dep[j]]=true;
}
this.Pk[i]={};//[];
dep=find('@order:');//模块文件调入次序
if (dep){
for (var j = 0; j < dep.length; j++) {
dep[j]=(dep[j] || "").replace( /^\s+|\s+$/g, "" );
this.Pk[i][dep[j]+'.js']=this.config(src[i][dep[j]+'.js']);
}
}else{
this.Pk[i][i+'.js']=this.config(module);
}
}
this.sort();
if (license) return this.packer(license);
return this;
},
/*把 源文件根据配置分段存储与Pk,以便后续处理*/
config:function(module){
function slice(tn,b1,p,max){//把string第2段分成2段
var begin=tn.begin;
var end=tn.end;
var e1,b2,e2;
e1=module.indexOf(begin,b1);
if (e1<0 || e1>=max) return false;
b2=e1+begin.length;
if (b2<0 || b2>=max) return false;
e2=module.indexOf(end,b2);
if (e2<0 || e2>=max) return false;
p[0]=b1;p[1]=e1;
p[2]=b2;p[3]=e2;
p[4]=e2+end.length;
return true;
}
function toobj(str){
str=str.replace( /^\s+|\s+$/g, "" );
if(str.indexOf(',')==0) str=str.slice(1);
return Function('return {'+str+'};')();
}
function push(p){
if(0==obj.length){
obj.push(p);
return ;
}
var pos=false;
for(var i = 0;i < obj.length; ++i)
if (p.begin>obj[i].begin) pos=i+1;
if(pos==false)
obj=[].concat([p],obj);
else
obj = obj.slice(0,pos).concat([p],obj.slice(pos));
}
var obj=[];
/*config分析*/
var p=[0,0,0,0,0];
if(slice(this.Config.config,0,p,module.length)){
module=module.slice(p[0],p[1])+module.slice(p[2],p[3])+module.slice(p[4]);
if(slice(this.Config.remove,0,p,module.length)){
var remove=toobj(module.slice(p[2],p[3]));
if (typeof remove=='object')
for (var prop in remove){
if (typeof remove[prop] =='object'){
if (this.Remove[prop]==undefined)
this.Remove[prop]={};
for(var s in remove[prop])
this.Remove[prop][s]=remove[prop][s];
}else
this.Remove[prop]=remove[prop];
}
module=module.slice(p[0],p[1])+module.slice(p[4]);
}
for (var i in this.Config.tag) {
if(slice(this.Config.tag[i],0,p,module.length))
push({begin:p[1],end:p[4],name:i});
}
}
var pk=[];
var pos=0;
obj.push({begin:module.length,end:module.length});
for (var i = 0; i < obj.length;i++) {
pk.push({src:module.slice(pos,obj[i].begin),name:obj[i].name||''});
pos=obj[i].end;
}
return pk;
},
/**
* 根据依赖关系生成 module 打包次序
*/
sort:function(){
function find(str){
for (var i=0;i<order.length;i++) {
if (order[i]==str) return i;
}
return null;
}
var order=this.Order=[];
var pos;
for (var i in this.Dep) {
pos=find(i);
if(pos!=null) {
for (var j in this.Dep[i]) {
if (typeof this.Dep[i][j] !='boolean') continue;
var pos2=find(j);
if (pos2<pos) continue;
var str=order[pos];
order[pos]=order[pos2];
order[pos2]=str;
}
continue;
}
for (var j in this.Dep[i]) {
if (typeof this.Dep[i][j] !='boolean') continue;
pos=find(j);
if(pos!=null) continue;
order.push(j);
}
order.push(i);
}
return;
},
/**
* 多粒度获取依赖关系 this.Dep 的信息
* this.Dep 整个依赖关系
* this.Dep[module] 某个 module 的依赖关系
* this.Dep[module][dep] 检查某个 module 是否依赖于 dep
*/
getdep:function(module,dep){
if(undefined==module && undefined==dep) return this.Dep;
if(dep && this.Dep[module])
return this.Dep[module][dep];
return this.Dep[module];
},
/**
* 多粒度获取 this.Remove 的信息
*/
getremove:function(key){
if (undefined==key)
return this.Remove;
return this.Remove[key];
},
/**
* 生成打包前的数据
* modules:[]
*/
prePacker:function(modules){
var pack={};
for (var i =0 ;i<modules.length;i++) {
pack[modules[i]]=[];
for (var j in this.Dep[modules[i]]) {
pack[j]=[];
}
}
var prepack=this.Data.prePack={};
for (var i = 0; i < this.Order.length; i++) {
var m=this.Order[i];
if(pack[m]){
for(var j in this.Pk[m])
pack[m]=pack[m].concat(this.Pk[m][j]);
prepack[m]=pack[m];
}
}
return this;
},
/*给不同的需求留下的自定义处理数据处理对象*/
Data:{},
nicEdit:function(pre,iconsPath){
if(!pre) pre='';
if(iconsPath)
iconsPath='"'+iconsPath+'"';
else
iconsPath='nicEditIconsPath';
var prePack=this.Data.prePack;
var pack=[];
if(typeof pre=='string') pack.push(pre);
var pos=0;
var iconList=[];
/*偷懒的图片全部打包*/
for (var i in this.Remove.iconFiles)
iconList.push('"'+i+'":'+(++pos));
iconList = '{'+iconList.join()+'}';
for(var i in prePack)
for(var j=0;j<prePack[i].length;j++){
pack.push(prePack[i][j].src);
if(''==prePack[i][j].name) continue;
switch(prePack[i][j].name){
case 'iconsPath':
pack.push(iconsPath);
break;
case 'iconList':
pack.push(iconList);
break;
}
}
this.Data.pack=pack.join('');
},
/**
* 配置语法
*/
Config:{
/*配置文件*/
configfile:'nicConfig.js',
/*配置开始和结束*/
config:{
begin:'/* START CONFIG */',
end:'/* END CONFIG */'},
/*需要删除的代码*/
remove:{
begin:'/* NICEDIT_REMOVE_START */',
end:'/* NICEDIT_REMOVE_END */'},
tag:{/*需要替换的配置*/
/*合并图标文件的URL路径*/
iconsPath:{
begin:'/* NICEDIT_ICONSPATH_START */',
end:'/* NICEDIT_ICONSPATH_END */'},
/*图标和标号列表*/
iconList:{
begin:'/* NICEDIT_ICONLIST_START */',
end:'/* NICEDIT_ICONLIST_END */'}
}
}
}
模块打包器
3868

被折叠的 条评论
为什么被折叠?



