首页 > 编程 > JavaScript > 正文

根据配置文件加载js依赖模块

2019-11-20 13:34:10
字体:
来源:转载
供稿:网友

要求:

根据下面的配置文件

复制代码 代码如下:

module=[
{'name':'jquery','src':'/js/lib/jquery-1.8.3.js'},
{'name':'swfobject','src':'/js/utils/swfobject.js'},
{'name':'fancybox','src':'/js/jquery/jquery.fancybox.js','require':['jquery']},
{'name':'uploadify','src':'/js/utils/uploadify.js','require':['swfobject']},
{'name':'jqform','src':'/js/jquery/jquery.form.js','require':['jquery']},
{'name':'register','src':'/js/page/reg.js','require':['jqform']},
{'name':'login','src':'/js/page/login.js','require':['fancybox','jqform']},
{'name':'upload','src':'/js/page/upload.js','require':['fancybox','jqform','uploadify']}
]

写一个函数

def getfiles(name)

返回 加载某个name指定的页面,要加载的js文件列表,有依赖的要先加载

小菜解法

    此题粗看起来很简单,实则不然。

     难点在于依赖模块的加载时机。假如有这样的依赖关系:A-B&C、B-C,A模块依赖B模块和C模块,同时B模块又依赖了C模块,总不能让C加载两次吧!

     小菜给出的这个解法,只是一个思路,肯定有比这更好的算法,小菜觉得可以用二叉树之类的算法解决,但小菜不会呀~~~

     此算法没有考虑循环依赖的情景。

     代码如下:

复制代码 代码如下:

 /**
  * 不考虑循环依赖
  * @type {Function}
  */
 var loadModule = (function(){
     /**
      * 业务逻辑封装
      * @type {{chainHead: {}, chainCurrent: {}, srcCache: {}, main: main, load: load, findModule: findModule}}
      */
     var logics = {
         chainHead: {},     //链表头
         chainCurrent: {},  //链表当前节点
         srcCache: {},      //module src 缓存
         /**
          * 对外接口
          * @param modules  配置对象
          * @param name  模块名称
          * @returns {Array} 依赖模块列表,按照加载先后顺序排列
          */
         main: function(modules, name){
             var nameArray = [],  //模块名称列表
                 srcArray = [],   //依赖模块列表
                 nameStr = "",    //模块名称字符串集
                 repeatRegex = /(^| )([/w]+ ).*/2/,  //模块名称去重正则
                 i = 0;
             //粗略加载所有依赖模块
             this.load(modules, name)
             //构造模块名称字符串集
             this.chainCurrent = this.chainHead;
             while(this.chainCurrent.next){
                 nameArray.push(this.chainCurrent.name);
                 this.chainCurrent = this.chainCurrent.next;
             }
             nameStr = nameArray.join(" ") + " ";  //统一标准,末尾补一个空格
             //依赖模块去重
             while(repeatRegex.exec(nameStr)){
                 nameStr = nameStr.replace(repeatRegex, function(g0, g1, g2){
                     return g0.substring(0, (g0.length - g2.length));
                 });
             }
             nameStr = nameStr.substring(0, (nameStr.length - 1));  //去掉补充的多余空格
             //依赖模块名称转换为模块路径
             nameArray = nameStr.split(" ");
             for(i = 0; i < nameArray.length; i++){
                 srcArray.push(this.srcCache[nameArray[i]]);
             }
             return srcArray;
         },
         /**
          * 递归加载模块
          * @param modules  配置对象
          * @param name  模块名称
          */
         load: function(modules, name){
             var node = {},
                 module = this.findModule.call(modules, "name", name),
                 i = 0;
             //判断模块是否存在
             if(!module){
                 throw Error("依赖模块 " + name +" 未找到");
             }
             //构造模块依赖链表
             node.name = name;
 //            node.src = module.src;
             this.srcCache[name] = module.src;
             node.next = this.chainHead;
             this.chainHead = node;
             //递归依赖
             if(module.require && module.require.length){
                 for(i = 0;i < module.require.length; i++){
                     this.load(modules, module.require[i]);
                 }
             }
         },
         /**
          * 根据指定属性名称和属性值查找模块
          * @param name  属性名称
          * @param value  属性值
          * @returns {*}
          */
         findModule: function(name, value){
             var array = this,
                 item = {},
                 i = 0;
             //遍历模块
             for(i = 0; i < array.length; i++){
                 item = array[i];
                 //获取指定模块
                 if(item && item[name] === value){
                     return item;
                 }
             }
             //找不到返回null
             return null;
         }
     };
     //暴露对外接口
     return function(){
         return logics.main.apply(logics, arguments);
     };
 }());
 /**
  * Test Usecase
  * @type {*[]}
  */
 var modules=[
     {'name':'jquery','src':'/js/lib/jquery-1.8.3.js'},
     {'name':'swfobject','src':'/js/utils/swfobject.js'},
     {'name':'fancybox','src':'/js/jquery/jquery.fancybox.js','require':['jquery']},
     {'name':'uploadify','src':'/js/utils/uploadify.js','require':['swfobject']},
     {'name':'jqform','src':'/js/jquery/jquery.form.js','require':['jquery']},
     {'name':'register','src':'/js/page/reg.js','require':['jqform']},
     {'name':'login','src':'/js/page/login.js','require':['fancybox','jqform']},
     {'name':'upload','src':'/js/page/upload.js','require':['fancybox','jqform','login','uploadify']}
 ];
 console.log(loadModule(modules, "upload"));

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表