webpack学习笔记(8)
学习笔记
配置区分环境
针对开发环境和生产环境, 可以抽离不同环境特定的配置和公共配置, 针对传入的环境参数生成不同的配置.
首先在config目录下新建通用配置文件, 生产环境配置文件, 开发环境配置文件. 现将原先webpack.config.js的内容复制到webpack.common.js
1 |
|
webpack 通过--config
指定配置文件, 通过--env
指定环境变量.
之前的webpack.config.js
是导出一个对象:
1 |
|
设置环境变量后导出值需要变为函数:
1 |
|
然后运行webpack --config ./config/webpack.common.js --env production
, 可以看到终端打印env
输出:
1 |
|
然后将参数赋值给process.env.NODE_ENV
, 通过这种方式区分当前环境, 这样babel.config.js, postcss.config.js等文件也能过读取环境变量.
需要注意的一点是, process.env
设置的属性都会转换为字符串, true
-> 'true'
, undefined
-> 'undefined'
, 不能简单通过!
关键字判断, 这是容易弄错的地方.
然后就是抽离通用配置, 开发环境使用的配置, 生产环境使用的配置, 这里以之前[[2022-09-30-study-webpack-day7#示例代码]]举例:
Code splitting
代码拆分(code splitting)是 webpack 一个非常重要的特性.
主要目的是将代码分离到不同的 bundle 中, 之后我们可以按需加载, 或者并行加载这些文件; 比如默认情况下, 所有的 JavaScript 代码(业务代码, 第三方以来, 暂时没有用到的模块) 在首页全部加载就会影响首页加载速度;代码分离可以分出更小的 bundle, 以及控制资源加载优先级, 提供代码的加载性能
先看下没有做任何处理的打包结果, 随便引入几个第三方库:
1 |
|
引入第三方库打包默认会生成 LICENSE.txt 文件, 可以先忽略.
可以看到打包结果, 第三方库源码也被打包进了入口文件中.
此时我们就需要代码分离来进行优化,
Webpack 常见的代码分离有三种:
- 入口起点: 使用 entry 配置手动分离代码
- 防止重复: 使用 Entry Dependencies 或者 SplitChunksPlugin 去重和分离代码
- 动态导入: 通过模块内联函数调用来分离代码
入口起点
当单入口文件中存在没有耦合关系的代码时, 可以通过配置多个入口文件来减小单个文件的体积.
1 |
|
拆分为:
1 |
|
配置 entry:
1 |
|
当然一般情况下 React/Vue 框架的 SPA 页面都是单入口文件, 在多页面打包时才会使用这种方案.
防止重复
存在 Enty Dependencies 和 SplitChunksPlugin 两种方案来进行代码分离, 其中绝大部分情况都是使用 SplitChunksPlugin, Entry Dependencies 官方并不推荐.
Entry Dependuncies
对于引入的第三方库, entry 也可以将其作为入口文件, 值可以是 string 或 Array. 引用第三方库的入口文件配置和之前有所变化.
1 |
|
打包结果可以看到第三方库代码被单独打包了.
SplitChunksPlugin
webpack 官方推荐通过这个插件配置, 通过optimization.splitChunks配置, 官方的配置样例:
1 |
|
下面介绍其中常用的配置字段, 其余的使用默认配置即可.
chunks
:async | initial | all
, 默认为async, 只针对异步(import() 或 require.ensure )导入的模块进行代码分离; initial只针对同步导入模块代码分离; all对同步和异步导入的模块都会进行代码分离, 一般都设置为all.minSize
: 文件大小(包括引入的包)达到minSize才会拆分maxSize
: 将大于maxSize的文件拆分为不小于minSize大小的文件, 一般用于二次拆分保证每个包文件不会过大, 一般情况下minSize和maxSize使用默认值即可, 即使手动设置也最好保持两者一直. BTW, minSize优先级大于maxSize, 即使配置maxSize小于minSize, 当然这样配置是绝对错误的.minChunks
: 默认为1, 模块被minChunks个入口文件引用时才会拆分, 一般都是单入口文件, 用默认值即可cacheGroups
: 针对不同的文件夹下的包文件进行更细致的打包配置, chunks, minChunks也可在cacheGroup中使用test
: 正则匹配文件夹filename
: 打包的文件名, 配置和output.filename
一致priority
: 优先级, 当多个 cacheGroup 匹配上时, 使用优先级最高的reuseExistingChunk
: 如果当前包文件已经被打包, 直接使用打包文件
chunkIds
:natural | named | deterministic
, 默认为deterministic, webpack 生成的唯一 id 作为 filename 或 chunkFilename 的[name]
, 如果文件内容不变, 生成的 id 也不会改变;natural
使用正整数作为[name]
, 不利于浏览器缓存, 不推荐;named
, 使用文件的路径+文件名作为[name]
, 开发环境下推荐使用, 见名知意.
可以看到使用不同chunkIds值打包后的输出:
1 |
|
其中, 异步导入的文件打包是特殊的. 无论chunks
配置什么, 异步导入的包都会进行打包, 并且cacheGroups
无法进行配置, 需要在output.chunkFilename
配置.
webpack 官网对output.chunkFilename
的定义即:
This option determines the name of non-initial chunk files.
怎么样, 你 kun 哥弔不弔, 你干嘛哎哟~
上述输出是对chunkFilename配置[name].[hash:6].vendor.js
的结果.
Magic Comment
除了chunkIds配置[name]
外, webpack 提供了魔法注释(Magic Comment)设置额异步导入文件打包后的[name]
, 并且魔法注释的优先级是最高的.
修改入口文件内容, 添加魔法注释:
1 |
|
查看打包结果:
1 |
|
最后想说, 关于 code splitting, 大部分情况下使用官方默认配置即可, 即使是 React/Vue 框架椰汁对小部分进行了修改:
Vue:
1 |
|
React更随便:
1 |
|
示例代码
https://github.com/Mariana-Yui/fe-learn-code/tree/main/learn-webpack/day8