`
achun
  • 浏览: 306698 次
  • 性别: Icon_minigender_1
  • 来自: 河南郑州
社区版块
存档分类
最新评论

根据nicEdit代码风格制作的js模块打包工具

阅读更多

根据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 */'}
		}
  }
}

 

0
0
分享到:
评论
2 楼 minglelui 2010-03-08  
请教下楼主,类似JQuery.pack.js文件是否也是通过类似的工具生成的,可有其他的工具介绍下?想了解对js和css文件打包的工具
1 楼 radovi 2009-10-25  
学习了……

相关推荐

Global site tag (gtag.js) - Google Analytics