<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      kmdjs集成uglifyjs2打造極致的編程體驗

      2016-06-14 19:13  【當耐特】  閱讀(1230)  評論(0)    收藏  舉報

      回顧

      上篇文章大概展示了kmdjs0.1.x時期的編程范式:
      如下面所示,可以直接依賴注入到function里,

      kmdjs.define('main',['util.bom','app.Ball','util.dom.test'], function(bom,Ball,test) {
          var ball = new Ball(0, 0, 28, 1, -2, 'kmdjs');
          var vp = bom.getViewport();
      });
      

      也可以直接在代碼里把full namespace加上來調用,如:

      kmdjs.define('main',['util.bom','app.Ball','util.dom.test'], function() {
          var ball = new app.Ball(0, 0, 28, 1, -2, 'kmdjs');
          var vp = util.bom.getViewport();
      });
      

      而且,在循環依賴的場景,因為執行順序的問題,會導致第一種方式注入undefined,所以循環依賴的情況下只能用full namespace的方式來調用。

      這種編程體驗雖然已經足夠好,但是可以更好。怎樣才算更好?

      1. 不用依賴注入function
      2. 不用寫full namespace,自動匹配依賴

      如下所示:

      kmdjs.define('main',['util.bom','app.Ball','util.dom.test'], function() {
          var ball = new Ball(0, 0, 28, 1, -2, 'kmdjs');
          var vp = bom.getViewport();
      });
      

      這就要借助uglifyjs能力,把function的字符串替換成帶有namespace就可以實現上面的效果。

      uglifyjs依賴分析和代碼重構

      function fixDeps(fn,deps) {
          var U2 = UglifyJS;
          //uglify2不支持匿名轉ast
          var code = fn.toString().replace('function','function ___kmdjs_temp');
          var ast = U2.parse(code);
          ast.figure_out_scope();
          var nodes = [];
      
      
          ast.walk(new U2.TreeWalker(function (node) {
      
              if (node instanceof U2.AST_New) {
                  var ex = node.expression;
                  var name = ex.name;
                  isInWindow(name) || isInArray(nodes, node) || isInScopeChainVariables(ex.scope, name) || nodes.push({name:name,node:node});
              }
      
              if (node instanceof U2.AST_Dot) {
                  var ex = node.expression;
                  var name = ex.name;
                  var scope = ex.scope;
                  if (scope) {
                      isInWindow(name) || isInArray(nodes, node) || isInScopeChainVariables(ex.scope, name) || nodes.push({name:name,node:node});
                  }
              }
      
              if (node instanceof U2.AST_SymbolRef) {
                  var name = node.name;
                  isInWindow(name) || isInArray(nodes, node) || isInScopeChainVariables(node.scope, name) || nodes.push({name:name,node:node});
              }
          }));
      
          var cloneNodes = [].concat(nodes);
          //過濾new nodes 中的symbo nodes
          for (var i = 0, len = nodes.length; i < len; i++) {
              var nodeA = nodes[i].node;
              for (var j = 0, cLen = cloneNodes.length; j < cLen; j++) {
                  var nodeB = cloneNodes[j].node;
                  if (nodeB.expression === nodeA) {
                      nodes.splice(i, 1);
                      i--;
                      len--;
                  }
              }
          }
      
          for (var i = nodes.length; --i >= 0;) {
              var item = nodes[i],
                  node=item.node,
                  name=item.name;
              var fullName=getFullName(deps,name);
              var replacement;
              if (node instanceof  U2.AST_New) {
                  replacement = new U2.AST_New({
                      expression: new U2.AST_SymbolRef({
                          name:fullName
                      }),
                      args: node.args
                  });
              } else if (node instanceof  U2.AST_Dot) {
                  replacement = new U2.AST_Dot({
                      expression: new U2.AST_SymbolRef({
                          name: fullName
                      }),
                      property: node.property
                  });
              }else if(node instanceof U2.AST_SymbolRef){
                  replacement = new U2.AST_SymbolRef({
                          name: fullName
                  });
              }
      
              var start_pos = node.start.pos;
              var end_pos = node.end.endpos;
      
              code = splice_string(code, start_pos, end_pos, replacement.print_to_string({
                  beautify: true
              }));
          }
          return code.replace('function ___kmdjs_temp','function');
      }
      
      function getFullName(deps,name){
          var i= 0,
              len=deps.length,
                  matchCount= 0,
                  result=[];
      
          for(;i<len;i++) {
              var fullName = deps[i];
              if (fullName.split('.').pop() === name) {
                  matchCount++;
                  if (!isInArray(result, fullName))  result.push(fullName);
              }
          }
      
          if(matchCount>1){
              throw "the same name conflict: "+result.join(" and ");
          } else if(matchCount===1){
              return result[0];
          }else{
              throw ' can not find module ['+name+']';
          }
      }
      
      function splice_string(str, begin, end, replacement) {
          return str.substr(0, begin) + replacement + str.substr(end);
      }
      
      function isInScopeChainVariables(scope, name) {
          var vars = scope.variables._values;
          if (Object.prototype.hasOwnProperty.call(vars, "$" + name)) {
              return true;
          }
      
          if (scope.parent_scope) {
              return isInScopeChainVariables(scope.parent_scope, name);
          }
      
          return false;
      }
      
      function isInArray(arr,name){
          var i= 0,len=arr.length;
          for(;i<len;i++){
              if(arr[i]===name){
                  return true;
              }
          }
          return false;
      }
      
      function isInWindow(name){
          if(name==='this')return true;
          return name in window;
      }
      

      通過上面的fixDeps,可以對代碼就行變換。如:

       console.log(fixDeps(function (A) {
              var eee = m;
              var b = new A();
              var b = new B();
              var c = new C();
              var d = G.a;
          },['c.B','AAA.G','SFSF.C','AAAA.m'] ))
      

      輸出:

      function (A) {
              var eee = AAAA.m;
              var b = new A();
              var b = new c.B();
              var c = new SFSF.C();
              var d = AAA.G.a;
      }
      

      這樣,kmdjs在執行模塊function的時候,只需要fixDeps加上full namespace就行:

      function buildBundler(){
          var topNsStr = "";
          each(kmdjs.factories, function (item) {
              nsToCode(item[0]);
          });
          topNsStr+=  kmdjs.nsList.join('\n') +"\n\n";
          each(kmdjs.factories, function (item) {
              topNsStr+=item[0]+' = ('+ fixDeps(item[2],item[1])+')();\n\n' ;
          });
          if(kmdjs.buildEnd) kmdjs.buildEnd(topNsStr);
          return topNsStr;
      }
      

      build出來的包,當然全都加上了namespace。再也不用區分循環依賴和非循環依賴了~~~

      Github

      上面的所有代碼可以Github上找到:
      https://github.com/kmdjs/kmdjs

      主站蜘蛛池模板: 亚洲天堂av免费在线看| 亚洲中文字幕五月五月婷| 国产久免费热视频在线观看| 最近中文字幕国产精品| 国产成熟女人性满足视频| 国产成人精品亚洲资源| 99re6这里有精品热视频| 一区二区三区午夜无码视频| 成人网站国产在线视频内射视频| 欧美人禽杂交狂配| 72种姿势欧美久久久久大黄蕉 | 国产精品日韩av一区二区| 大香伊蕉在人线国产免费| 午夜射精日本三级| 四虎在线中文字幕一区| 精品久久人人妻人人做精品| 欧美日本国产va高清cabal| 高清无码18| 国产精品亚洲综合网一区| 毛片无码免费无码播放| 亚洲在av极品无码天堂| 午夜免费福利小电影| 瑞昌市| 久久免费观看午夜成人网站| 国产在线一区二区不卡| 无遮挡又黄又刺激的视频| 日韩精品一区二区蜜臀av| 婷婷六月色| 久热视频这里只有精品6| 国产精品中文一区二区| 东方四虎在线观看av| 久久久无码精品亚洲日韩蜜臀浪潮| 啦啦啦高清在线观看视频www| 国产欧美另类精品久久久| 国产三级无码内射在线看| 午夜久久一区二区狠狠干| 久久精品国产一区二区蜜芽| 妖精视频yjsp毛片永久| 国产麻豆放荡av激情演绎| 成人无码精品1区2区3区免费看| 亚洲成人av一区二区|