• webpack打包文件解析


    /**

      * 对于没有代码分割的,webpack会打包生成main.js一个大的自执行函数

      * 函数参数是一个对象,键值分别是路径和模块的函数

      * 函数内部定义了一些方法,包括__webpack_require__

      * 函数内部执行逻辑会从一个入口开始进行webpackrequire按内部依赖的逻辑来执行函数

      *

      */

    /*

      对于有代码分割的内容,webpack除了main.js还会生成0.js,1.js...等

    20191026补充注:

    此分析时,使用了dynamic-import-webpack插件,实际webpack4可以不引入这个插件,不引入的话,动态import('xx.js').then(中直接拿到的是module,而不是下面分析中直接拿到的可执行函数名,后文整个分析流程和动态包的加载逻辑没有变化。 

    原始代码:

    index.js:

    show.js:

    sb.js:

    show-child.js:

    打包生成的main.js里的大自执行函数的函数参数是这样的:

    (./src/index.js是入口)

    下面的自执行函数是这样的:

    被转换成了

    先执行__webpack_require__.e然后在then里面resolve(__webpack_require__(‘./src/show.js))

    __webpack_require__.e是干什么的:

    webpack_require__.e内部声明了一个空数组promises

    功能:

    1.该函数会修改在大自执行函数中定义的installedChunks (显示安装chunk的状态)

     

    2.创建了一个installedChunkData对象 是installedChunks[chunkId]

      对象的结构是[resolve,reject,promise]

    3.如果正在加载

      会执行

    promises.push(installedChunkData[2]);   <- - -这里的[2]就是promise对象

             否则 创建一个新promise对象

      4.创建script标签:

     

    __webpack_require__.e函数创建了一个script标签,引入0.js..等 插入到head标签的后面

    返回一个promise,promise.then里面可以拿到一个数组,[]数组中内容是           ( return Promise.all(promises)    // Promise {<pending>}

    __webpack_require__.e函数最终返回的是一个promise     (  这个promise后面then的调用时机是——promises数组里所有promise对象都确定了完成状态

    总结:  __webpack_require__.e是创建一个script标签,然后异步加载, 函数最后返回一个promise ,当promise被resolve或reject的时候(即,require__.e创建的promises数组里所有元素都有了确定状态时)可以被后面的.then接收到

     

     当创建的script标签加载完成了,promise就会被resolve或reject,

    看一下创建的标签的内容:

    2.js内容:

    创建的这个script标签(异步加载)的内容是什么呢,拿2.js来分析一下:

    window.webpackJsonp数组 中使用push方法 : [[2],{‘….’:{  }}]

    此时的push方法已经被改写了:

    window下jsonpArray的push方法是webpackJsonpCallback

    于是调用 webpackJsonpCallback([[2],{‘…’{}}]

    执行:

    该方法会将chunk们的加载状态记录管理,将moreModules装载到modules中

    后面的resolves.shift()()会导致_webpack_require__.e里产生的promise对象resolve出来,

    到这里一个chunk加载完成,将会执行_webpack_require__.e.then后面的逻辑

    流程:创建script标签加载chunk

       chunk 指一个要异步加载的大数据块 在这个例子中0.js,1.js,2.js就是chunk

      然后chunk里面一般是这样的 然后调用被改写过的window.webpackJsonp.push方法进行加载,将chunk们的加载状态记录管理,将moreModules装载到modules中

    总结:__webpack_require__.e 会创建script标签src地址是依赖的js文件,将这个script标签插入到head标签后面,最终返回一个promise对象

    被创建好的script标签内容是一段会被立即执行的表达式,使用window.webpackJsonp.push(被改写过的一个方法)方法来装载管理chunk安装状态,并将moremodules插入 到modules中。 还调用到了__webpack_require__.e中创建的promise的resolve()方法 ,当resolve结束后,__webpack_require__.e 的promise对象的.then方法也会被触发。(因为__webpack_require__.e中最终返回的是Promise.all([…]))

     

    仓库地址 https://github.com/eret9616/webpack-bundle.js

    分支 asyncloading syncloading  

    直接以dist目录启动服务

    附:

    webpack_require__.r  将这个module标记为esModule ,重写Symbol.toStringTag接口,添加__esModule属性 (Symbol.toStringTag是什么:普通对象的toString是'object Object',修改Symbol.toStringTag接口后,toString可以变成'object xxxx')

    webpack_require__.t  当import('...xxx.js')动态引入一个commonjs模块的时候,会创建一个对象,将这个对象标记为esModule,将commonjs模块转换得到等价的esModule的内容输出

  • 相关阅读:
    053(二十五)
    053(二十四)
    053(二十三)
    053(二十二)
    053(二十一)
    053(二十)
    053(十九)
    053(十八)
    053(十七)
    单例设计模式
  • 原文地址:https://www.cnblogs.com/eret9616/p/11395117.html
Copyright © 2020-2023  润新知