摘要
代码分离(分包)
概念:将代码分离到不同的产物包中,之后可以通过按需或者并行的方式来加载这些文件。
Webpack 常用的代码分离方式:
1-多入口起点:配置多入口:使用entry配置不同的入口文件。手动来分离代码。
2-动态导入:动态导入:import() 语法动态导入模块
3-防止重复:使用Entry Dependencies
或者SplitChunksPlugin
去重和分离代码。
optimization
optimization.chunkIds:用于告知webpack模块的id采用什么算法生成。
optimization.runtimeChunk:配置runtime相关的代码,决定是否将其抽取到一个单独的chunk中
Prefetch和Preload
- prefetch(预获取):在浏览器空闲时进行低优先级的资源预加载。
- preload(预加载):用于提示浏览器尽早加载某些资源。
实践经验:
- 开发中推荐使用 prefetch。prefetch会在浏览器闲置时下载并缓存,从而在用户导航到需要这些资源的页面时能够更快地加载。
CDN
概念:内容分发网络,是一种通过分布式的服务器来加速网络内容交付的技术。
使用场景:
- 部署静态资源到CDN服务器上,然后引入对应资源
- CDN引入依赖包
代码分离
概念
问题背景:
Webpack打包后只有一个文件 bundle.js
,然后将它引入到用户界面。
问题是,bundle.js
这个文件很大,浏览器加载会很耗时间,就会有一个白屏显示。
**解决方案:**代码分离(Code Splitting)
概念:
代码分离(Code Splitting)的主要目的是将代码分离到不同的bundle中,之后可以通过按需或者并行的方式来加载这些文件。
举例:
比如默认情况下,所有的JavaScript代码(业务代码、第三方依赖、暂时没有用到的模块)在首页全部都加载,就会影响首页 的加载速度。
代码分离可以分出更小的bundle,以及控制资源加载优先级,提供代码的加载性能。
Webpack中常用的代码分离有三种:
多入口起点:使用entry配置手动分离代码。
动态导入:通过模块的内联函数调用来分离代码。
SplitChunks 防止重复:使用Entry Dependencies
或者SplitChunksPlugin
去重和分离代码。
多入口起点
配置多入口
**概念:**配置多入口。
**具体操作:**比如配置一个index.js和main.js的入口。要点如下:
- 配置 entry,设定分包
- 配置 output,设定分包产物的名称
filename: '[name]-bundle.js'
webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode: 'development',
devtool: false,
/***************************************************************************/
entry: {
index: './src/index.js',
main: './src/main.js'
},
output: {
path: path.resolve(__dirname, './build'),
filename: '[name]-bundle.js',
clean: true
},
/***************************************************************************/
resolve: {
},
devServer: {
},
module: {
},
plugins: [
]
}
index.html
进行包的引入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script defer src="./build/index-bundle.js"></script>
<script defer src="./build/main-bundle.js"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>
入口依赖
问题背景:
假如我们的index.js
和main.js
都依赖两个库:lodash、dayjs
如果我们单纯地进行入口分离,那么打包后的两个bunlde都会有一份lodash和dayjs。
这样会造成资源重复占用。
**解决方案:**入口依赖(Entry Dependencies)
通过 shared
来让两份入口文件共享相同包。
具体操作:
webpack.config.js
entry: {
index: {
import: './src/index.js',
dependOn: 'shared'
},
main: {
import: './src/main.js',
dependOn: 'shared'
},
shared: ['lodash', 'dayjs']
},
npm run build
之后的产出如下:
.
├── index-bundle.js
├── index.html
├── main-bundle.js
└── shared-bundle.js
可以发现,产物中多了一份 shared-bundle.js
,该文件是 index.js
和main.js
产物文件的共享的依赖包。
另外一个代码拆分的方式是动态导入:
动态导入
**概念:**webpack提供两种动态导入的方式: