摘要:怎樣才算更好不用依賴注入不用寫,自動匹配依賴如下所示這就要借助能力,把的字符串替換成帶有就可以實現上面的效果。再也不用區分循環依賴和非循環依賴了上面的所有代碼可以上找到
回顧
上篇文章大概展示了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的方式來調用。
這種編程體驗雖然已經足夠好,但是可以更好。怎樣才算更好?
不用依賴注入function
不用寫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(;i1){ 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 通過上面的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(" ") +" "; each(kmdjs.factories, function (item) { topNsStr+=item[0]+" = ("+ fixDeps(item[2],item[1])+")(); " ; }); if(kmdjs.buildEnd) kmdjs.buildEnd(topNsStr); return topNsStr; }build出來的包,當然全都加上了namespace。再也不用區分循環依賴和非循環依賴了~~~
Github上面的所有代碼可以Github上找到:
https://github.com/kmdjs/kmdjs
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/79667.html
摘要:華三通信云計算產品線總裁吳健這樣說到。雖然低調如斯,但這絲毫沒有影響華三通信在云計算領域內的江湖地位。相比起來,華三通信發布的超融合系統產品則更加廣為人知。 從引力波到AlphaGo,從虛擬現實到新能源,從電子政務到云課堂,云計算早已不再是高高在上的概念,而是已經滲透到了科技、工作、生活的每一個角落。 云計算的大行其道,不但改變了科技行業原有的技術路線,更是改變了既有的產業格局,創新、融...
摘要:從很早的版本就開始,是支持循環依賴的。比如下面的代碼會被編譯成要支持循環依賴其實有個要求,就是。不是的循環依賴是無解的循環依賴。所以在初始化階段,這樣的循環依賴是被允許的,因為都是。 循環依賴 循環依賴是非常必要的,有的程序寫著寫著就循環依賴了,可以提取出一個對象來共同依賴解決循環依賴,但是有時會破壞程序的邏輯自封閉和高內聚。所以沒解決好循環依賴的模塊化庫、框架、編譯器都不是一個好庫、...
閱讀 1512·2021-11-24 09:38
閱讀 3366·2021-11-18 10:02
閱讀 3253·2021-09-22 15:29
閱讀 2937·2021-09-22 15:15
閱讀 1037·2021-09-13 10:25
閱讀 1834·2021-08-17 10:13
閱讀 1971·2021-08-04 11:13
閱讀 1973·2019-08-30 15:54