最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解webpack2異步加載套路

 更新時(shí)間:2018年09月14日 09:13:19   作者:蘋果小蘿卜  
這篇文章主要介紹了詳解webpack2異步加載套路,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

webpack提供的一個(gè)非常強(qiáng)大的功能就是code spliting(代碼切割)。

在webpack 1.x中提供了

  require.ensure([], () => {
    let module = require('./page1/module');
    // do something
  }, 'module1')

利用require.ensure這個(gè)API使得webpack單獨(dú)將這個(gè)文件打包成一個(gè)可以異步加載的chunk.

具體的套路見我寫的另一篇blog: webpack分包及異步加載套路

一句話總結(jié)就是:

在輸出的runtime代碼中,包含了異步chunk的id及chunk name的映射關(guān)系。需要異步加載相應(yīng)的chunk時(shí),通過生成script標(biāo)簽,然后插入到DOM中完成chunk的加載。通過JSONP,runtime中定義好函數(shù),chunk加載完成后即會(huì)立即執(zhí)行這個(gè)函數(shù)。

從編譯生成后的代碼來看,webpack 1.x從chunk的加載到執(zhí)行的過程處理的比較粗糙,僅僅是通過添加script標(biāo)簽,異步加載chunk后,完成函數(shù)的執(zhí)行。

這個(gè)過程當(dāng)中,如果出現(xiàn)了chunk加載不成功時(shí),這種情況下應(yīng)該如何去容錯(cuò)呢?

在webpack2中相比于webpack1.x在這個(gè)點(diǎn)的處理上是將chunk的加載包裹在了promise當(dāng)中,那么這個(gè)過程變的可控起來。具體的webpack2實(shí)現(xiàn)套路也是本文想要去說明的地方。

webpack提供的異步加載函數(shù)是

  /******/   // This file contains only the entry chunk.
/******/   // The chunk loading function for additional chunks
      // runtime代碼里面只包含了入口的chunk
      // 這個(gè)函數(shù)的主要作用:
      // 1. 異步加載chunk
      // 2. 提供對(duì)于chunk加載失敗或者處于加載中的處理
      // 其中chunk加載狀態(tài)的判斷是根據(jù)installedChunks對(duì)象chunkId是數(shù)字0還是數(shù)組來進(jìn)行判斷的
/******/   __webpack_require__.e = function requireEnsure(chunkId) {
        // 數(shù)字0代表chunk加載成功
/******/     if(installedChunks[chunkId] === 0) 
/******/       return Promise.resolve();

/******/     // an Promise means "currently loading".
        // 如果installedChunks[chunkId]為一個(gè)數(shù)組
/******/     if(installedChunks[chunkId]) {
          // 返回一個(gè)promise對(duì)象
/******/       return installedChunks[chunkId][2];
/******/     }
/******/     // start chunk loading
        // 通過生成script標(biāo)簽來異步加載chunk.文件名是根據(jù)接受的chunkId來確認(rèn)的
/******/     var head = document.getElementsByTagName('head')[0];
/******/     var script = document.createElement('script');
/******/     script.type = 'text/javascript';
/******/     script.charset = 'utf-8';
/******/     script.async = true;
        // 超時(shí)時(shí)間為120s
/******/     script.timeout = 120000;

/******/     if (__webpack_require__.nc) {
/******/       script.setAttribute("nonce", __webpack_require__.nc);
/******/     }
        // 需要加載的文件名
/******/     script.src = __webpack_require__.p + "js/register/" + ({"2":"index"}[chunkId]||chunkId) + ".js";
        // 120s的定時(shí)器,超時(shí)后觸發(fā)onScriptComplete回調(diào)
/******/     var timeout = setTimeout(onScriptComplete, 120000);
        // chunk加載完畢后的回調(diào)
/******/     script.onerror = script.onload = onScriptComplete;
/******/     function onScriptComplete() {
/******/       // avoid mem leaks in IE.
/******/       script.onerror = script.onload = null;
          // 清空定時(shí)器
/******/       clearTimeout(timeout);
          // 獲取這個(gè)chunk的加載狀態(tài)
          // 若為數(shù)字0,表示加載成功
          // 若為一個(gè)數(shù)組, 調(diào)用數(shù)組的第2個(gè)元素(第二個(gè)元素為promise內(nèi)傳入的reject函數(shù)),使得promise捕獲拋出的錯(cuò)誤。reject(new Error('xxx'))
/******/       var chunk = installedChunks[chunkId];
/******/       if(chunk !== 0) {
/******/         if(chunk) chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));
/******/         installedChunks[chunkId] = undefined;
/******/       }
/******/     };
        
        // 每次需要進(jìn)行異步加載chunk時(shí),會(huì)將這個(gè)chunk的加載狀態(tài)進(jìn)行初始化為一個(gè)數(shù)組,并以key/value的形式保存在installedChunks里
        // 這個(gè)數(shù)組為[resolve, reject, promise];
/******/     var promise = new Promise(function(resolve, reject) {
/******/       installedChunks[chunkId] = [resolve, reject];
/******/     });
/******/     installedChunks[chunkId][2] = promise;

/******/     head.appendChild(script);
        //返回promise
/******/     return promise;
/******/   };

我們?cè)賮砜纯绰酚膳渲梦募幾g后生成的代碼index.js, 特別注意下__webpack_require__.e這個(gè)異步加載函數(shù):

Router
.home('path1')
.addRoute({
  path: 'path1',
  animate: 'zoomIn',
  viewBox: '.public-path1-container',
  template: __webpack_require__(5),
  // 掛載controller
  pageInit: function pageInit() {
    var _this = this;

    console.time('route async path1');
    // 異步加載0.js(這個(gè)文件是webpack通過code spliting自己生成的文件名)
    // 具體異步加載代碼的封裝見?分析
    // 其中0.js包含了包含了path1這個(gè)路由下的業(yè)務(wù)代碼
    // __webpack_require__.e(0) 起的作用僅為加載chunk以及提供對(duì)于chunk加載失敗錯(cuò)誤的拋出
    // 具體的業(yè)務(wù)代碼的觸發(fā)是通過__webpack_require_e(0).then(__webpack_require__.bind(null, 8)).then(function(module) { ... })進(jìn)行觸發(fā)
    // __webpack_require__.bind(null, 8) 返回的是module[8]暴露出來的module
    // 這段代碼執(zhí)行時(shí),首先初始化一個(gè)module對(duì)象
    // module = {
    //    i: moduleId, // 模塊id
    //    l: false,   // 加載狀態(tài)
    //    exports: {}  // 需要暴露的對(duì)象
    //  }
    // 通過異步加載的chunk最后暴露出來的對(duì)象是作為了module.exports.default屬性
    // 因此在第二個(gè)方法中傳入的對(duì)象的default屬性才是你模塊8真正所暴露的對(duì)象
    __webpack_require__.e/* import() */(0).then(__webpack_require__.bind(null, 8)).then(function (module) {
      var controller = module.default;
      Router.registerCtrl('path1', new controller(_this.viewBox));
    // 添加錯(cuò)誤處理函數(shù),用以捕獲前面可能拋出的錯(cuò)誤
    }).catch(function (e) {
      return console.log('chunk loading failed');
    });
  },

  // 進(jìn)入路由跳轉(zhuǎn)之前
  beforeEnter: function beforeEnter() {},

  // 路由跳轉(zhuǎn)前
  beforeLeave: function beforeLeave() {}
})
.addRoute({
  path: 'path2',
  viewBox: '.public-path2-container',
  animate: 'zoomIn',
  template: __webpack_require__(6),
  pageInit: function pageInit() {
    var _this2 = this;

    __webpack_require__.e/* import() */(1).then(__webpack_require__.bind(null, 9)).then(function (module) {
      console.time('route async path2');
      var controller = module.default;
      Router.registerCtrl('path2', new controller(_this2.viewBox));
    }).catch(function (e) {
      return console.log('chunk loading failed');
    });
  },
  beforeEnter: function beforeEnter() {},
  beforeLeave: function beforeLeave() {}
});

Router.bootstrap();

總結(jié)一下就是:

webpack2相比于webpack1.x將異步加載chunk的過程封裝在了promise當(dāng)中,如果chunk加載超時(shí)或者失敗會(huì)拋出錯(cuò)誤,這時(shí)我們可以針對(duì)拋出的錯(cuò)誤做相應(yīng)的錯(cuò)誤處理。

此外還應(yīng)該注意下,webpack2異步加載chunk是基于原生的promise。如果部分環(huán)境暫時(shí)還不支持原生promise時(shí)需要提供polyfill。另外就是require.ensure可以接受第三個(gè)參數(shù)用以給chunk命名,但是import這個(gè)API沒有提供這個(gè)方法

更多的細(xì)節(jié)大家可以運(yùn)行demo看下編譯后的代碼

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • javascript獲取web應(yīng)用根目錄的方法

    javascript獲取web應(yīng)用根目錄的方法

    這篇文章主要介紹了javascript獲取web應(yīng)用根目錄的方法,需要的朋友可以參考下
    2014-02-02
  • Mac系統(tǒng)下Webstorm快捷鍵整理大全

    Mac系統(tǒng)下Webstorm快捷鍵整理大全

    webstorm應(yīng)該是目前最強(qiáng)的js編輯器了,結(jié)合sublime text可以很效率的開發(fā)項(xiàng)目。下面這篇文章主要給大家整理了一些Mac系統(tǒng)下Webstorm快捷鍵的相關(guān)資料,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-05-05
  • layUI實(shí)現(xiàn)三級(jí)導(dǎo)航菜單效果

    layUI實(shí)現(xiàn)三級(jí)導(dǎo)航菜單效果

    這篇文章主要為大家詳細(xì)介紹了layUI實(shí)現(xiàn)三級(jí)導(dǎo)航菜單效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-07-07
  • 微信小程序form表單組件示例代碼

    微信小程序form表單組件示例代碼

    這篇文章主要介紹了微信小程序form表單組件示例代碼,文章給大家提到了一些相關(guān)屬性名和類型及說明,需要的朋友可以參考下
    2018-07-07
  • 為JS擴(kuò)展Array.prototype.indexOf引發(fā)的問題探討及解決

    為JS擴(kuò)展Array.prototype.indexOf引發(fā)的問題探討及解決

    Array沒有indexOf方法,這樣在一個(gè)數(shù)組中查找某個(gè)元素的索引時(shí)比較麻煩,于是通過prototype原型擴(kuò)展了Array.prototype.indexOf(),在對(duì)數(shù)組進(jìn)行遍歷的時(shí)候卻出現(xiàn)了問題
    2013-04-04
  • JS判斷日期格式是否合法的簡(jiǎn)單實(shí)例

    JS判斷日期格式是否合法的簡(jiǎn)單實(shí)例

    下面小編就為大家?guī)硪黄狫S判斷日期格式是否合法的簡(jiǎn)單實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-07-07
  • js數(shù)字轉(zhuǎn)中文兩種實(shí)現(xiàn)方法

    js數(shù)字轉(zhuǎn)中文兩種實(shí)現(xiàn)方法

    在前端開發(fā)中有時(shí)候會(huì)需要到將阿拉伯?dāng)?shù)字轉(zhuǎn)化為中文,當(dāng)前做個(gè)記錄,提供自己之后翻閱,這篇文章主要給大家介紹了關(guān)于js數(shù)字轉(zhuǎn)中文兩種實(shí)現(xiàn)方法的相關(guān)資料,需要的朋友可以參考下
    2023-10-10
  • webpack+vue2構(gòu)建vue項(xiàng)目骨架的方法

    webpack+vue2構(gòu)建vue項(xiàng)目骨架的方法

    本篇文章主要介紹了webpack+vue2構(gòu)建vue項(xiàng)目骨架的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-01-01
  • JS庫(kù)之Highlight.js的用法詳解

    JS庫(kù)之Highlight.js的用法詳解

    highlight.js是一款輕量級(jí)的Web代碼語法高亮庫(kù)。下面通過實(shí)例代碼給大家分享JS庫(kù)之Highlight.js的用法詳解,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧
    2017-09-09
  • js+jquery常用知識(shí)點(diǎn)匯總

    js+jquery常用知識(shí)點(diǎn)匯總

    本文主要介紹了jquery源碼中常見的知識(shí)點(diǎn)以及javascript中原型鏈常見的知識(shí)點(diǎn),非常的全面,這里推薦給小伙伴們。
    2015-03-03

最新評(píng)論

曲松县| 香港| 姚安县| 简阳市| 荣昌县| 海城市| 兴城市| 井冈山市| 渭源县| 彭州市| 遂溪县| 嘉禾县| 蒙城县| 武山县| 临江市| 沙河市| 辉南县| 云安县| 永济市| 乐亭县| 山西省| 上思县| 定兴县| 会同县| 都兰县| 密山市| 潼南县| 时尚| 嘉祥县| 隆化县| 全州县| 嘉峪关市| 南安市| 西和县| 德惠市| 原阳县| 福泉市| 桐城市| 普定县| 泾川县| 于田县|