深入浅出 webpack 之基础配置篇 (6)

如果不进行特殊的配置, Tree Shaking 会误认为 xxx.css 只导入了,但是没有使用,因此相关 css 代码会被删除,当配置为 ["*.css"] 时,会排除所有 css 文件不做 Tree Shaking 处理。

Code Splitting

代码分割,顾名思义就是把打包好的代码的进行分割。

看一个场景:

import { forEach } from "lodash-es"; forEach([1,2,3],(item)=>{ console.log(item); })

执行打包命令:

深入浅出 webpack 之基础配置篇

我们发现 lodash 也被打包进 bundle.js 了。

在实际开发中,我们可能会使用多种类库共同工作,如果都打包到 bundle.js 中,那么这个文件势必会非常大!

还有另外一个问题就是,我们打包的静态文件都会添加相应的 hash 值,如下配置:

output: { filename: '[hash]_bundle.js', // 打包出的文件类似:07b62441b18e3aaa6c93_bundle.js path: path.resolve(__dirname,'dist') }

这么做的目的想必大家都知道,就是浏览器会对同一个名字的静态资源进行缓存,假设我们不添加 hash 值,但是线上又发现了 bug,我再次打包后把静态资源更新到服务器后,用户的浏览器由于有缓存是不会立马显示最新效果的,而需要手动去清空缓存。

一般外部引入的类库文件是不会改变的,而我们的业务代码是会经常变动的。我们把会变动的和不变动的代码都打包到一起,显然是不合理的,至少会造成当我们重新打包后,用户需要加载全部的代码。

假如我们做了代码分割再配合浏览器的缓存机制,用户网站只需要加载更新后的业务代码,而类库的代码则不需要重新加载。

以上就是我们需要做代码分割的理由。接下来我们看看 webpack 中可以如何进行代码分割配置。

SplitChunksPlugin

它的配置应该算是 webpack 插件中比较复杂的配置了而且又非常重要,因此本文会详细讲解它的核心配置的含义。

我们有以下两种方式引入一个第三方模块:

同步方式:

import { forEach } from "lodash"; import $ from "jquery"; $(function () { forEach([1,2,3],(item)=>{ console.log(item); }) });

异步方式:

import("lodash").then(({default:_})=>{ console.log(_.join(["a","b"],"-")); })

SplitChunksPlugin 插件已经提供了一套开箱即用的默认配置,让我们可以快速对以上两种模块引入方式进行代码分割打包优化。下面我们来分析下它的默认配置的意思:

optimization: { splitChunks: { chunks: 'async', minSize: 30000, minRemainingSize: 0, maxSize: 0, minChunks: 1, maxAsyncRequests: 6, maxInitialRequests: 4, automaticNameDelimiter: '~', cacheGroups: { defaultVendors: { test: /[\\/]node_modules[\\/]/, priority: -10 }, default: { minChunks: 2, priority: -20, reuseExistingChunk: true } } } } chunks

async 异步模块生效

initial 同步模块生效

all 异步同步都生效

minSize

chunk 文件最小打包尺码,例如这里默认设置是 30000 kb ,假设我们要打包的库小于 30000kb 则不会进行分模块打包。

maxSize

最大打包尺寸,假设 lodash 为 1MB ,这里设置为 500KB ,webpack 会尝试把 lodash 拆分成2个文件,但其实 lodash 这种类库是不好做拆分的,所以最终结果是一样的,只会打出一个包。

minChunks

一个模块被用了多少次才对它进行代码分割。

maxAsyncRequests

最多加载的 chunk 数量

maxInitialRequests

入口文件做代码分割的最大数量

automaticNameDelimiter

文件名的连接符

name

设置为 true 时,cacheGroups 中的 filename 才能生效

cacheGroups

缓存组,该对象里面的 defaultVendors 与 default 相当于两条模块缓存数组。
一般是同步引入的模块,命中该缓存策略就把该模块 push 到该数组中,最后合并输出一个 chunk。

缓存策略是这样配置的:

cacheGroups: { vendors: { chunks: 'initial', // 只针对同步模块 test: /[\\/]node_modules[\\/]/, // 对同步代码进行打包时,会先判断是否在node_modules下面 priority: -10, // 打包一个模块有可能既符合vendors的规则也符合default的规则,这个时候根据priority的来判断选择哪个值越大优先级越高 filename: '[name].chunk.js' // 输出的文件名 }, default: { minChunks: 2, // 当模块被使用了两次 priority: -20, // 表示权限值 reuseExistingChunk: true // 会去检查循环引用,避免打包一些无用的模块进来 } }

同步模块打包:

import { forEach } from "lodash"; import $ from "jquery"; $(function () { forEach([1,2,3],(item)=>{ console.log(item); }) });

分析:

lodash 模块命中 vendors 策略,推入 vendors 策略缓存组中;

jquery 模块同样命中 vendors 策略,推入 vendors 策略缓存组中;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpyygz.html