webpack打包之后的同步&异步代码

232 阅读1分钟

最近再次研究了一下webpack打包后代码形式, 网上查找文章加自己实际查看, 于是手写了一个简约的版本 留作备用哈




// webpack唯一暴露出来的全局变量
window.webpackJsonp = []


// 同步加载
(function(modules){
  // 同步安装的 models
    const installmodels = {}
    // 异步加载
    var installedChunks = {
      "main": 0
    };
    // 异步加载 
    webpackjsonp.push = webpackJsonpCallback 
  
    function _webpack_require(modleid) {
      if (installmodels[modleid]) return installmodels[modleid].exports

      var model = installmodels[modleid] =  {
        exports : {}
      }
      modules[moduleId].call(model.exports, model)


    }
    // 异步加载 
    function requireEnsure(chunkId) {
      var installedChunkData = installedChunks[chunkId];
      
      var script  = document.createElement('script')
      script.src =  chunkId + ".bundle.js";
      var head = document.getElementsByTagName('head')[0];
      head.appendChild(script);
      
      function scriptcompeltte(event) {
        script.onerror = script.onload = null;
         var chunk = installedChunks[chunkId];
         if(chunk !== 0) {
            var realSrc = event.target.src
            const error = new Error(url+ 'load error' + realSrc)

            chunk[1](error);
         }
      }
      script.onload = script.onerror = scriptcompeltte
  
  
  
      var promise = new promise( (rel, rej) => {
        installedChunkData = installedChunks[chunkId] = [resolve, reject];
      })
      return  promise
    }
    // 异步加载 
    function webpackJsonpCallback(data) {
      var chunkIds = data[0];
      // 对应的模块详细信息,详见打包出来的 chunk 模块中的 push 进 window["webpackJsonp"] 中的第二个参数
      var moreModules = data[1];
      var chunkId, resolves = [];
      // 收集 下载 完成的文件的 id, 准备下面给resove
      for(var i = 0; i<chunkIds.length; i++) {
        chunkId = chunkIds[i];
        if(installedChunks[chunkId]) {
          resolves.push(installedChunks[chunkId][0]);
        }
        // 标记成已经执行完
        installedChunks[chunkId] = 0;
      }
      // 赋值给全局唯一的 modules 
      for(moduleId in moreModules) {
            if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
              modules[moduleId] = moreModules[moduleId];
            }
      }
      // 把下载时new的promise 给 resolve(),
      while(resolves.length) {
        resolves.shift()();
      }
    }

    // 主入口
   _webpack_require('src/index.js')

})({
 'src/index.js': function(model, __webpack_exports__){
   function sayHello(name) {
    return `Hello ${name}`;
  }
  __webpack_exports__["default"] = (sayHello);
 }
 ,
 'src/page.js': function(model, _webpack_require_){}
})


// 下载的 异步trunk
(webpackjsonp || []).push([0], {
  'src/another.js': function(model,__webpack_exports__) {
    model.exports  = another
    function another() { console.log('anther')}

  }
})

参考 juejin.cn/post/693708…