日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

echarts与TmodJS的冲突 -- 模块化加载器之间的冲突

發布時間:2025/7/25 javascript 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 echarts与TmodJS的冲突 -- 模块化加载器之间的冲突 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

  前些日子寫了一篇關于騰訊模板引擎TmodJS的文章《模板引擎artTemplate及模板預編譯器TmodJS的使用入門》,算是對其原理與使用進行了初步的接觸與研究。近期在一個項目中對TmodJS進行了嘗試,未曾想無意中居然發現了TmodJS與百度圖表神器Echarts之間存在一個看似不能共存的沖突。

  問題是這樣的:項目的某個頁面中同時顯式地引入了Echarts的主文件“echarts.js”以及TmodJS的依賴文件“require.js”。當執行到TmodJS所需的require()方法時,腳本會報“Error: [REQUIRE_FATAL]Relative ID is not allowed in global require”的錯誤,進而導致模板無法被加載以及渲染。報錯如圖所示:

  

  從報錯信息上看,問題存在于echarts以及require方法上。這個項目中的Echarts均采用模塊化方式進行加載,而TmodJS也需要通過“require.js”來實現編譯后模板的加載以及后續的DOM渲染。但前者內置的是百度自己實現的模塊化加載器“esl”,因為此前對echarts的實現有著一些粗淺的了解,因此我認為問題很有可能和esl拋出的require方法與require.js拋出的同名方法不兼容相關。

  由于頁面中先引入了esl,其在加載成功之后便在window對象中留下了全局方法require和define。而隨后引入的require.js在加載時由于檢測到了上述兩個方法的存在,則認為自身已有實例存在而不會繼續進行加載(若繼續加載則會覆蓋esl的兩個同名方法)。require.js的相關代碼如下:

  雖然兩者拋出方法的名稱一致,但它們所需參數的內容卻并不相同。兩者require方法所需的第一個參數均為array類型,但require.js需要的array中直接存放的就是模塊相對路徑的字串。而esl需要的參數更為復雜一些,其先要通過require.config方法,將相對路徑的字串設置到一個object中的一個名為paths的object的指定key中,而后在使用其自己定義的require時,會將之前指定的key依次壓入array中并將這個array作為第一個參數。兩者在require方法所需參數上的差異,最終導致了上述腳本錯誤的出現。看似兩個風馬牛不相及的東西,居然因為模塊化加載器之間的沖突產生了交集,確實讓人小意外了一下。

  既然問題的原因已經確定,那么我們就可以嘗試進行解決了。我的解決思路是,默認在頁面中不顯式引入require.js。在TmodJS需要使用require方法之前,先對當前瀏覽器環境的require進行判定。如果加載了esl,則將模塊相對路徑按照esl需要的方式配置、轉化,進而通過esl加載。如果已存在自身或其它amd加載器拋出的require方法,則直接調用。如果干脆就不存在require方法,則動態地加載require.js。具體代碼如下:

  // 代碼簡陋,還請各位路過的高手見諒。如有疏漏還請海涵、指正

  function NeedReq(arg){ // 參數形如{
???????????????                   list:{  // 指定模塊的名稱和相對路徑
???????????????????                     'tmpl':'../../js/template'
???????????????                   },
???????????????                   callback:function(template){ // 指定require方法加載之后的回調
???????????????????                     // some code...
???????????????                   },
???????????????                   reqPath:'../../js/require.js'  // 指定require.js的相對路徑
???????????                  }

    //? description: 智能判斷頁面是否加載了esl并由此決定是否加載require.js
    //? author: Liyanyang(gudaozr)
    //? version: 1.1

???   var reqPath = [], reqRelativePath = [], reqCallback = null;  // 分別定義esl、require.js所用參數數組以及require.js動態加載成功后制定的回調函數
???   var objIsEmpty = function(obj){  // 檢測對象是否為空的函數,這里主要用于判斷傳進來的參數是否有效
???????   if(typeof obj != 'object'){
???????????   return false;
???????   }
???????   for(var key in obj){
???????????   return false;
???????   }
???????   return true;
???   };

???   if(!arguments.length){ // 參數有效性、完整性判斷,不符合直接pass~
???????   return false;
???   }else if(!arg.list || objIsEmpty(arg.list)){
???????   return false;
???   }else if(typeof arg.callback != 'function'){
???????   return false;
???   }else if(!arg.reqPath){
???????   return false;
???   }

???   var i = 0;
???   for(var key in arg.list){ // 按照esl和require.js需求生成不同內容形式的參數數組
???????   reqPath[i] = key;
???????   reqRelativePath[i++] = arg.list[key];
???   }

???   reqCallback = arg.callback;

???   if(window.require && window.require.loader == 'esl'){?????? // esl已經加載,不需要require.js
???????   require.config({
???????????   paths:arg.list
???????   });
???????   require(reqPath,reqCallback);
???   }else if(!window.require){????? // esl和require.js均未加載,需要加載require.js
???????   var scrNode = document.createElement('script');
???????   scrNode.setAttribute('src',arg.reqPath);
???????   var scripts = document.getElementsByTagName('script');
???????   if(scripts.length){
???????????   var scrParent = scripts[0].parentNode;
???????????   if(scripts.length == 1){
???????????????   scrParent.insertBefore(scrNode,scripts[0]);
???????????   }else{
???????????????   scrParent.insertBefore(scrNode,scripts[1]);
???????????   }
???????????   scrNode.onload = function(){
???????????????   require(reqRelativePath,reqCallback);
???????????   }
???????   }
???   }else if(window.require && define.amd){???? //? require.js或者其它amd加載器已經加載
???????   require(reqRelativePath,reqCallback);
???   }

??? return true;

}

  寥寥草草記錄了下這個問題的發現以及解決,真心希望能夠幫到遇到同類問題的朋友。如果文章中存在什么錯誤或者不周之處,還請各位高手批評、指正。期待與大家進行交流!

轉載于:https://www.cnblogs.com/gdzr/p/5179862.html

總結

以上是生活随笔為你收集整理的echarts与TmodJS的冲突 -- 模块化加载器之间的冲突的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。