zoukankan      html  css  js  c++  java
  • 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的内容输出

  • 相关阅读:
    Minimum Depth of Binary Tree leetcode java
    Maximum Depth of Binary Tree leetcode java
    Symmetric Tree leetcode java
    Same Tree leetcode java
    Binary Tree Postorder Traversal leetcode java
    Binary Tree Preorder Traversal leetcode java
    Binary Tree Inorder Traversal leetcode java
    Combinations leetcode java
    一键清除Centos iptables 防火墙所有规则
    阿里云centos7.7x64安装open,并配置ip转发和nat伪装
  • 原文地址:https://www.cnblogs.com/eret9616/p/11395117.html
Copyright © 2011-2022 走看看