参考链接1

由一个问题引出 CodeSpliting

业务代码 第三方库 代码分开

1.首先安装第三方库 - lodash

npm i loadsh —save

2.在index.js 中引入这个库

  1. import _ from 'lodash';
  2. console.log(_.join(['a','b','c'],'***'))

3.打包,发现问题

我们看打包后的main.js ,发现目前所有的业务代码 lodash工具代码都打包在了一起。
实际情况下,业务代码是非常多的。如果现在按照这样打包会把两者打包到一起,从代码运行层面上是没有任何问题的;
但是也有一个潜在的问题:假设 lodash 体积很大,有1MB;业务代码也有1MB;在不压缩main.js 代码的情况下,main.js 代码有2MB,如果用户访问index.js页面就需要等待 2MB 加载完后才能看到。
问题:

  • 导致打包文件太大,加载时间太长,影响体验;
  • 其实lodash库的代码并不怎么会变化。但是当业务代码改动后,如果用户重新访问页面的话,又必须重新加载2MB的包。根本没有必要再次加载lodash的代码。(后面会缓存这些工具代码,这样二次加载页面的时候就不会再重新加载这些工具代码了,直接从缓存中拿)

webpack中的代码分离

对于⼤的 Web 应⽤来讲,将所有的代码都放在⼀个⽂件中显然是不够有效的,特别是当你的
某些代码块是在某些特殊的时候才会被使⽤到。webpack 有⼀个功能就是将你的代码库分割成
chunks(语块),当代码运⾏到需要它们的时候再进⾏加载。
适用的场景:

  • 公用代码拆分出来;(例如第三方库等工具类库)(同步过程?)

    联想vue:业务代码(app) 和 第三方库代码(vendor)分离 第三方库代码由于很少像本地的源代码那样频繁修改,因此可以利用浏览器的缓存来消除请求。

  • 业务代码拆分成一小块,等到需要的时候再加载(异步模块引入和拆分)(即动态引入,懒加载)

    联想vue:业务代码分离成一块一块的,使得初始下载的代码更小

  • 暂时没有用到的模块

代码分离的三种方式

  • 入口起点:使用 entry 配置手动地分离代码;
  • 防止重复:使用 Entry Dependencies(entry 配置中的 dependOn 选项 )或 splitChunksPlugin 去重和分离 chunk;
  • 动态导入:通过模块的内联函数(如import)调用来分离代码。

1)多入口起点

入口起点的含义非常简单,就是配置多入口。
比如有两个文件src/main.js、src/index.js,在webpack.common.js里配置:

  1. entry: {
  2. main: "./src/main.js",
  3. index: "./src/index.js"
  4. },
  5. output: {
  6. path: resolveApp("./build"),
  7. filename: "[name].bundle.js"
  8. }

2)Entry Dependencies(入口依赖)

假如我们的index.js和main.js都依赖两个库:lodash、dayjs。
如果我们单纯的进行入口分离,那么打包后的两个bunlde都有会有一份lodash和dayjs;事实上我们可以对他们进行共享。

  1. entry: {
  2. main: { import: "./src/main.js", dependOn: "shared" },
  3. index: { import: "./src/index.js", dependOn: "shared" },
  4. lodash: "lodash",
  5. // dayjs: "dayjs"
  6. shared: ["lodash", "dayjs"]
  7. }

3)splitChunksPlugin

另外一种分包的模式是splitChunk,它是使用 SplitChunksPlugin 来实现的,用于import文件或者第三方包的时候:

  • 因为该插件webpack已经默认安装和集成,所以我们并不需要单独安装和直接使用该插件;只需要提供SplitChunksPlugin相关的配置信息即可。
  • Webpack提供了SplitChunksPlugin默认的配置,我们也可以手动来修改它的配置。

    相关笔记链接

4)动态导入(dynamic import)

最后一种代码拆分的方式是动态导入,主要是EM6中的import() 语法。

相关笔记链接

总结