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')}
}
复制代码

outputchunkFilename 决定了非入口(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 名以 outputchunkFilename 设置的格式打包到 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 等,比如 lodashbabel-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:代码分割相关推荐

  1. webpack代码分割和懒加载

    代码分割: 分离业务代码 和 第三方依赖 分离业务代码 和业务公共代码 和第三方依赖 分离首次加载 和 访问加载后的代码 常用的:require.ensure() []:denpendencies c ...

  2. Webpack进阶(二)代码分割 Code Splitting

    源代码index.js里包含2部分 ① 业务逻辑代码 1mb ② 引入(如lodash包)的代码 1mb 若更新了业务逻辑代码,但在浏览器运行时每次都下载2mb的index.js显然不合理,第三方包是 ...

  3. css-6 df15,webpack 样式文件的代码分割(15)

    获取全套webpack 4.x教程,请访问瓦力博客 在上一小节,我们将开发环境和生产环境区分开来.这一小节,我们来操作如何将样式文件的代码分割. 1.安装 yarn add mini-css-extr ...

  4. webpack打包生成的map文件_一站式搞明白webpack中的代码分割

    上次分析到通过devtool的配置项来设置source map,在线上环境可以通过设置成cheap-module-source-map来生成单独的map文件,但是map文件在线上环境会不会每次都加载呢 ...

  5. 【Webpack 性能优化系列(6) - code splitting 】通过代码分割来获取更小的 bundle,优化资源加载

    webpack系列文章: [Webpack 性能优化系列(9) - 多进程打包]极大的提升项目打包构建速度!!! [Webpack 性能优化系列(8) - PWA]使用渐进式网络应用程序为我们的项目添 ...

  6. 13 代码分割之import静动态导入

    前端首屏优化方案之一 项目构建时会整体打包成一个bundle的JS文件,而有的代码.模块是加载时不需要的,需要分割出来单独形成一个文件块chunk(不会打包在main里),让模块懒加载(想加载时才加载 ...

  7. 前端每周清单第 30 期:WebVR 指南,Vue 代码分割范式,理想的 React 架构特性

    前端每周清单专注前端领域内容,以对外文资料的搜集为主,帮助开发者了解一周前端热点:分为新闻热点.开发教程.工程实践.深度阅读.开源项目.巅峰人生等栏目.欢迎关注[前端之巅]微信公众号(ID:front ...

  8. css练习题4,复习webpack4之CSS文件代码分割

    之前学习过webpack3的知识,但是webpack4升级后还是有很多变动的,所以这次重新整理一下webpack4的知识点,方便以后复习. 这次学习webpack4不仅仅要会配置,记住核心API,最好 ...

  9. 代码分割(Code Splitting)

    代码分割(Code Splitting) 为什么要分割代码?代码分割有什么作用呢? 答:两个方面. 1.项目包含第三方依赖库以及自己写的代码,打包出的文件会比较大,在用户访问系统的时候,由于请求的资源 ...

最新文章

  1. 特斯拉D1芯片遭实名diss:内存到封装都成问题,网友:反正不能公开测评
  2. 什么是静态路由,其特点是什么?什么是动态路由,其特点是什么?
  3. Android Studio 1.1的安装和遇到的坑
  4. sql net message from client
  5. CF Round #580(div2)题解报告
  6. Chrome 浏览器访问不了任何网页
  7. 制作双绞线时,T568b、T568a 线序分别是什么?
  8. 利用Oracle RDA( Remote Diagnostic Agent)快速收集Oracle产品分析数据
  9. php ckfinder 无效请求.,解决nginx和php使用ckfinder无法上传大文件的问题
  10. Android手机怎么找回微信好友,安卓手机微信好友删除怎么找回?这三种方法真香...
  11. jenkins 配置代理
  12. Redis 的高并发实战:抢购系统 --浅奕
  13. 基于云平台的电力供电设备远程监控系统
  14. AIS 2019(ACL IJCAI SIGIR)论文研讨会研究趋势汇总
  15. 重来之大学版|学习篇-为什么要学习?为什么要终身学习?别一上来就“费曼学习法”,先学习学习再学习
  16. 初入职场“荒野求生”,五条靠谱的生存指南
  17. C++ 算法篇 广度(宽度)优先搜索(BFS)
  18. 计算机网络八股文-面试必问
  19. 牛客网剑指offer java 全部题解
  20. lettuce MGET性能分析

热门文章

  1. python3 ocr_python3 ocr 识别图片文字(CSDN验证码90%通过)
  2. coursera 计算概论与程序设计基础(李戈)-第一题
  3. docker使用之私有仓库构建(四)
  4. Spark RDD Action 简单用例(一)
  5. python数据结构list的extend与append的差别
  6. fedora下做成liveOS的U盘容量变小问题
  7. Qt/Embedded开发环境的的搭建(二)
  8. 虚拟化技术、云计算服务模式、Docker安装
  9. 深度学习李宏毅PPT学习笔记一(深度学习介绍)
  10. Linux下的web调度器——squid实现(负载均衡)