阅读 140

工程化知识卡片 004: webpack 中的 code spliting 是如何动态加载 chunk 的?

一个 webpack 中运行时,包括最重要的两个数据结构:

  1. __webpack_modules__: 维护一个所有模块的数组。将入口模块解析为 AST,根据 AST 深度优先搜索所有的模块,并构建出这个模块数组。每个模块都由一个包裹函数 (module, module.exports, __webpack_require__) 对模块进行包裹构成。

  2. __webpack_require__(moduleId): 手动实现加载一个模块。对已加载过的模块进行缓存,对未加载过的模块,根据 id 定位到 __webpack_modules__ 中的包裹函数,执行并返回 module.exports,并缓存。

在 webpack 中,通过 import() 可实现 code spliting.

import('./sum').then(m => {   m.default(3, 4) }) // 以下为 sum.js 内容 const sum = (x, y) => x + y export default sum 复制代码

使用 import() 加载数据时,以上代码将被 webpack  编译为以下代码

__webpack_require__.e(/* import() | sum */ 644).then(__webpack_require__.bind(__webpack_require__, 709)).then(m => {   m.default(3, 4) }) 复制代码

每一个 chunk 的代码如下,以下为 sum 函数所构建而成的 chunk:

"use strict"; (self["webpackChunk"] = self["webpackChunk"] || []).push([[644],{ /***/ 709: /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {         __webpack_require__.r(__webpack_exports__);         /* harmony export */ __webpack_require__.d(__webpack_exports__, {         /* harmony export */   "default": () => (__WEBPACK_DEFAULT_EXPORT__)         /* harmony export */ });         const sum = (x, y) => x + y /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (sum); /***/ }) }]); 复制代码

以下两个数据结构是加载 chunk 的关键:

  1. __webpack_require__.e: 加载 chunk,如 644 为 chunkId。该函数将使用 JSONP (document.createElement('script'))异步加载 chunk 并封装为 Promise。

  2. self["webpackChunk"].push: JSONP cllaback,收集 modules,如 709 为 sum 模块的 id。该函数将 709 置入  __webpack_modules__ 中。

实际上,在 webpack 中可配置 output.chunkLoading 来选择加载 chunk 的方式

webpack({     entry: './index.js',     mode: 'none',     output: {       filename: 'main.[contenthash].js',       chunkFilename: '[name].chunk.[chunkhash].js',       path: path.resolve(__dirname, 'dist/import'),       clean: true,       // 默认为 `jsonp`       chunkLoading: 'import'     }   })


作者:shanyue
链接:https://juejin.cn/post/7016590445471875086


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐