Webpack:代码分割
webpack 版本:4.35.0
webpack-cli 版本:3.3.5
为什么需要代码分割
在当前的前端项目中,常常使用 gulp、webpack、Browserify 等将多个文件压缩合并成一个。这个过程称为打包。 打包是一个将文件引入并合并到一个单独文件的过程,最终形成一个 “bundle”。接着在页面上引入该 bundle,整个应用即可一次性加载。
打包是个非常棒的技术,但随着你的应用增长,你的代码包也将随之增长。尤其是在整合了体积巨大的第三方库的情况下。你需要关注你代码包中所包含的代码,以避免因体积过大而导致加载时间过长。
为了避免搞出大体积的代码包,在前期就思考该问题并对代码包进行分割是个不错的选择。代码分割是由诸如 Webpack(代码分割)和 Browserify(factor-bundle)这类打包器支持的一项技术,能够创建多个包并在运行时动态加载。
对应用进行代码分割能够帮助你“懒加载”当前用户所需要的内容,能够显著地提高你的应用性能。尽管并没有减少应用整体的代码体积,但你可以避免加载用户永远不需要的代码,并在初始加载的时候减少所需加载的代码量。
关键点
打包解决了项目中依赖文件过多,而导致 http 请求过多的问题
代码分割则是解决打包的副作用——单文件过大,导致加载时间过长。
因此代码分割的关键点在于,如何控制分割粒度:
- 分割文件多少
- 文件大小
分割方法
有三种常用的代码分离方法:
- 入口起点:使用
entry
配置手动地分离代码。 - 动态导入:通过模块的内联函数调用来分离代码。
- 使用插件手动分离
entry
每个 entry
都会在最后的打包中输出一个对应的文件。因此可以显示地进行代码分割:
module.exports = {entry: {app: './src/index.js',print: './src/print.js'},// ...output: {filename: '[name].[chunkhash].js',path: path.resolve(__dirname, './dist')}
}
复制代码
进行打包构建后会在 dist
文件夹输出:
app.f7badf83cc90de106d41.js
print.e00bba994e917cc7fc59.js
复制代码
动态导入
动态导入也可以达到代码分割的效果:
import _ from 'lodash';function component() {var element = document.createElement('div');// Lodash(目前通过一个 script 脚本引入)对于执行这一行是必需的element.innerHTML = _.join(['你好呀', 'webpack'], ' ');element.onclick = (e) => import(/* webpackChunkName: "print" */ './print').then((Print) => {})return element;
}document.body.appendChild(component());复制代码
webpackChunkName
设置了输出包的名字。
module.exports = {entry: {app: './src/index.js'},// ...output: {filename: '[name].[chunkhash].js',chunkFilename: '[name].[chunkhash].js',path: path.resolve(__dirname, './dist')}
}
复制代码
output
的 chunkFilename
决定了非入口(non-entry) chunk 文件的名称。这里的 chunk 是通过代码分割产生的,因此这里通过此选项来设置文件的名字。
运行打包:
app.73efde30ee057cb8c817.js
print.e4408db3b4e5072295de.js
复制代码
插件
CommonsChunkPlugin
在 webpack 4 之前,使用 CommonsChunkPlugin
进行公共 chunk 抽取。
module.exports = {entry: './src/index.js',entry: {main: './src/index.js',vendor: ['lodash']},plugins: [new CleanWebpackPlugin(['dist']),new HtmlWebpackPlugin({title: 'Caching'}),new webpack.optimize.CommonsChunkPlugin({name: 'vendor'}),new webpack.optimize.CommonsChunkPlugin({name: 'manifest'})],output: {filename: '[name].[chunkhash].js',path: path.resolve(__dirname, 'dist')}
};
复制代码
这里有两点值得注意:
entry
中的vendor
:显式引用lodash
,由于index.js
也导入了lodash
,因此它就变成了一个公共的模块。- 使用
new webpack.optimize.CommonsChunkPlugin
抽取这些公共模块
SplitChunksPlugin
webpack 4 之后 CommonsChunkPlugin
被弃用了,使用 SplitChunksPlugin
代替。 SplitChunksPlugin
是开箱即用的,只需要在 module.exports
中进行配置:
module.exports = {//...optimization: {splitChunks: { // 该选项将用于配置 SplitChunksPlugin 插件cacheGroups: {vendors: {test: /[\\/]node_modules[\\/]/,name: 'vendor',chunks: 'initial',minChunks: 2}}}},output: {filename: '[name].[chunkhash].js',chunkFilename: '[name].[chunkhash].js',path: path.resolve(__dirname, './dist')}
};
复制代码
上面的配置会将 node_modules
下引用的所有模块都使用 vendor
这个作为 chunk 名以 output
中 chunkFilename
设置的格式打包到 dist
文件夹中。
SplitChunksPlugin
的选项:
cacheGroups 中每一项都接收如下参数:
filename: 重写 chunk 命名方式
vendors: {test: /[\\/]node_modules[\\/]/,name: 'vendor',filename:'[name].bundle.js'chunks: 'initial',minChunks: 2, } 复制代码
最后会生成名字为
vendor.bundle.js
的文件关于 SplitChunksPlugin 插件的配置,请参见 SplitChunksPlugin 解析
分割内容
代码分割的关键点在于控制分割粒度:
- 分割文件多少
- 文件大小
如果在不考虑大小的情况下,最后会打包出包含所有代码的单个文件。我们可以 optimization.splitChunks.maxSize
来控制 chunk 的大小以达到分割成多文件的目的。
只通过大小来控制代码分割拥有如下弊端:
入口文件大小未得到最大的优化
不能使用缓存。
在项目中,有些引入的工具的更新频率是非常低的,这时候
表现和结构未进行分离。
浏览器进行渲染的时候,表现和结构是基于不同的算法进行解析的。并且,样式代码也会增加请求的响应时间。
三方库
在项目中,常常会引入一些三方的工具库或者 polyfill 等,比如 lodash
,babel-polyfill
。这些代码在项目中改动很少,因此建议将这些代码提取到一个单独的文件中。
这样做有几个好处:
- 可以进行缓存
- 优化入口文件大小
- 进行关注点分离
CSS
在项目中可以使用 ExtractTextWebpackPlugin 插件将 CSS 文件抽取到单独的 bundle 中。
entry: {polyfill: './src/utils/polyfill.js',main: './src/main.js',app: './src/index.js'
},复制代码
参考链接
代码分离
缓存
加载-polyfills
ExtractTextWebpackPlugin
转载于:https://juejin.im/post/5d19b08de51d455a2f2202b2
Webpack:代码分割相关推荐
- webpack代码分割和懒加载
代码分割: 分离业务代码 和 第三方依赖 分离业务代码 和业务公共代码 和第三方依赖 分离首次加载 和 访问加载后的代码 常用的:require.ensure() []:denpendencies c ...
- Webpack进阶(二)代码分割 Code Splitting
源代码index.js里包含2部分 ① 业务逻辑代码 1mb ② 引入(如lodash包)的代码 1mb 若更新了业务逻辑代码,但在浏览器运行时每次都下载2mb的index.js显然不合理,第三方包是 ...
- css-6 df15,webpack 样式文件的代码分割(15)
获取全套webpack 4.x教程,请访问瓦力博客 在上一小节,我们将开发环境和生产环境区分开来.这一小节,我们来操作如何将样式文件的代码分割. 1.安装 yarn add mini-css-extr ...
- webpack打包生成的map文件_一站式搞明白webpack中的代码分割
上次分析到通过devtool的配置项来设置source map,在线上环境可以通过设置成cheap-module-source-map来生成单独的map文件,但是map文件在线上环境会不会每次都加载呢 ...
- 【Webpack 性能优化系列(6) - code splitting 】通过代码分割来获取更小的 bundle,优化资源加载
webpack系列文章: [Webpack 性能优化系列(9) - 多进程打包]极大的提升项目打包构建速度!!! [Webpack 性能优化系列(8) - PWA]使用渐进式网络应用程序为我们的项目添 ...
- 13 代码分割之import静动态导入
前端首屏优化方案之一 项目构建时会整体打包成一个bundle的JS文件,而有的代码.模块是加载时不需要的,需要分割出来单独形成一个文件块chunk(不会打包在main里),让模块懒加载(想加载时才加载 ...
- 前端每周清单第 30 期:WebVR 指南,Vue 代码分割范式,理想的 React 架构特性
前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点:分为新闻热点.开发教程.工程实践.深度阅读.开源项目.巅峰人生等栏目.欢迎关注[前端之巅]微信公众号(ID:front ...
- css练习题4,复习webpack4之CSS文件代码分割
之前学习过webpack3的知识,但是webpack4升级后还是有很多变动的,所以这次重新整理一下webpack4的知识点,方便以后复习. 这次学习webpack4不仅仅要会配置,记住核心API,最好 ...
- 代码分割(Code Splitting)
代码分割(Code Splitting) 为什么要分割代码?代码分割有什么作用呢? 答:两个方面. 1.项目包含第三方依赖库以及自己写的代码,打包出的文件会比较大,在用户访问系统的时候,由于请求的资源 ...
最新文章
- 特斯拉D1芯片遭实名diss:内存到封装都成问题,网友:反正不能公开测评
- 什么是静态路由,其特点是什么?什么是动态路由,其特点是什么?
- Android Studio 1.1的安装和遇到的坑
- sql net message from client
- CF Round #580(div2)题解报告
- Chrome 浏览器访问不了任何网页
- 制作双绞线时,T568b、T568a 线序分别是什么?
- 利用Oracle RDA( Remote Diagnostic Agent)快速收集Oracle产品分析数据
- php ckfinder 无效请求.,解决nginx和php使用ckfinder无法上传大文件的问题
- Android手机怎么找回微信好友,安卓手机微信好友删除怎么找回?这三种方法真香...
- jenkins 配置代理
- Redis 的高并发实战:抢购系统 --浅奕
- 基于云平台的电力供电设备远程监控系统
- AIS 2019(ACL IJCAI SIGIR)论文研讨会研究趋势汇总
- 重来之大学版|学习篇-为什么要学习?为什么要终身学习?别一上来就“费曼学习法”,先学习学习再学习
- 初入职场“荒野求生”,五条靠谱的生存指南
- C++ 算法篇 广度(宽度)优先搜索(BFS)
- 计算机网络八股文-面试必问
- 牛客网剑指offer java 全部题解
- lettuce MGET性能分析
热门文章
- python3 ocr_python3 ocr 识别图片文字(CSDN验证码90%通过)
- coursera 计算概论与程序设计基础(李戈)-第一题
- docker使用之私有仓库构建(四)
- Spark RDD Action 简单用例(一)
- python数据结构list的extend与append的差别
- fedora下做成liveOS的U盘容量变小问题
- Qt/Embedded开发环境的的搭建(二)
- 虚拟化技术、云计算服务模式、Docker安装
- 深度学习李宏毅PPT学习笔记一(深度学习介绍)
- Linux下的web调度器——squid实现(负载均衡)