Webpack 4教程 - 第四部分,使用SplitChunksPlugin分离代码
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。
原文出处:https://wanago.io/2018/06/04/code-splitting-with-splitchunksplugin-in-webpack-4/
Webpack 4 给我们带来了一些变化。其中包括更快地打包,引入了SplitChunksPlugin,并淘汰掉之前的CommomsChunksPlugin。在本文,你将学习如何拆分输出代码以提高应用的性能。
代码分离的思想
先说重要的:在Webpack中,到底什么是代码分离?代码分离允许你把代码拆分到多个文件中。如果使用得当,你的应用性能会提高很多。因为浏览器能缓存你的代码。
每当你做出一次修改,包含修改的文件需要被所有访问你网站的人重新下载。但你并不会经常修改应用的依赖库(译者注:你常修改的是你的业务逻辑)。如果你能把那些依赖库拆分到完全分离的文件中,即使业务逻辑发生了更改,访问者也不需要再次下载依赖库,直接使用之前的缓存就可以了。
使用Webpack时,你会得到一个或多个生成的输出文件,这些文件包含了我们源码的最终输出。而它们由代码块(chunks)组成。
入口(Entry)
入口定义了我们代码中应用是从哪里开始执行的,这也是Webpack开始打包的地方。你可以定义一个入口(常见于单页应用),或者多个入口(常见于多页应用)。
定义一个入口,就会得到一个chunk。如果你只使用字符串定义一个入口,那么这个chunk名为main。如果你使用对象定义了多个入口,那么它们会以entry对象的属性来命名。下面的例子会得到相同的chunk:
// 例1
entry: './src/index.js'
// 例2
entry: {
main: './src/index.js'
}
输出(Output)
在配置文件中,输出配置是一个对象,它指明了Webpack应该在哪儿和如何对我们的打包结果和资源进行输出。虽然可能有多个入口,但是只能有一个输出配置对象。而chunk名称的用处,就在于根据入口对应不同的输出。你可以为我们的打包输出定义一个固定的文件名,但若想代码分离,就不应该这么做。你可以使用[name]为我们的输出文件创建文件名的模板:
output: {
filename: '[name].[chunkhash].bundle.js',
path: path.resolve(__dirname, 'dist')
}
一件值得注意的重要东西是[chunkhash]:它是一个基于文件内容的属于特定chunk的哈希值。它仅会随着文件内容的改变而改变。因此,浏览器就可以利用这一点来缓存它。如果打包输出的文件名变了,浏览器就知道自己需要重新下载它。一个chunkhash可能长这样:0c553ebfd158e16da428。
我们的主chunk会被打包进一个叫main.[chunkhash].bundle.js的文件。
SplitChunksPlugin
由于有了SplitChunksPlugin,你可以把应用中的特定部分移至不同文件。如果一个模块在不止一个chunk中被使用,那么利用代码分离,该模块就可以在它们之间很好地被共享。这是Webpack的默认行为。
// utilities/users.js
export default [
{ firstName: "Adam", age: 28 },
{ firstName: "Jane", age: 24 },
{ firstName: "Ben", age: 31 },
{ firstName: "Lucy", age: 40 }
]
// a.js
import _ from 'lodash';
import users from './users'; const adam = _.find(users, { firstName: 'Adam' });
// b.js
import _ from 'lodash';
import users from './users'; const lucy = _.find(users, { firstName: 'Lucy' });
// webpack.config.js
module.exports = {
entry: {
a: "./src/a.js",
b: "./src/b.js"
},
output: {
filename: "[name].[chunkhash].bundle.js",
path: __dirname + "/dist"
}
};
如果运行它,你会看到Webpack创建了两个文件:a.[chunkhash].bundle.js和b.[chunkhash].bundle.js,而且每一个文件都包含对lodash库的拷贝:这并不好!我之前说过,为共享的库创建分离的文件是Webpack的一个默认行为,但这只涉及异步的chunk,即意味着只作用于我们异步引入的那些文件。我们会在介绍懒加载的时候讨论这个话题。为了使这个默认行为能支持所有类型的chunks,我们需要稍微改一下Webpack的配置:
// webpack.config.js
module.exports = {
entry: {
a: "./src/a.js",
b: "./src/b.js"
},
output: {
filename: "[name].[chunkhash].bundle.js",
path: __dirname + "/dist"
},
optimization: {
splitChunks: {
chunks: "all"
}
},
};
现在我们看到,创建了额外的vendors~a~b.[chunkhash].bundle.js文件,它包含了lodash库的代码。这是因为我们默认有一些cacheGroups配置:
splitChunks: {
chunks: "all",
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
首先,是vendors,它包含的文件来自于你node_modules。再者,是所有其他共享模块的默认缓存组。这里有一个小点:有一些冗余。a.[chunkhash].bundle.js和b.[chunkhash].bundle.js都包含了users.js的内容。这是因为,SplitChunksPlugin默认地只会分离大于30Kb的文件。我们可以轻松地修改它:
// webpack.config.js
module.exports = {
entry: {
a: "./src/a.js",
b: "./src/b.js"
},
output: {
filename: "[name].[chunkhash].bundle.js",
path: __dirname + "/dist"
},
optimization: {
splitChunks: {
chunks: 'all',
minSize: 0 // 修改了这里
}
}
};
结果是,它新创建了属于默认缓存组的名为a~b.[chunkhash].bundle.js的文件。因为我们的users.js文件所占空间远远小于30Kb,在没有修改minSize属性的情况下,它不会被打包到单独的分离文件。在真实环境下,这是一件好事,因为这样不会带来实质的性能提升,反而会强制浏览器为分离出的文件(它现在是很小的)再发一次额外的请求。
我们可以进一步,为仅在utilities目录下的做特殊处理:
const HtmlWebpackPlugin = require('html-webpack-plugin'); module.exports = {
entry: {
a: "./src/a.js",
b: "./src/b.js"
},
output: {
filename: "[name].[chunkhash].bundle.js",
path: __dirname + "/dist"
},
optimization: {
splitChunks: {
chunks: "all",
cacheGroups: {
utilities: {
test: /[\\/]src[\\/]utilities[\\/]/,
minSize: 0
}
}
}
}
};
这样我们的输出包含4个文件:a.[chunkhash].bundle.js,b.[chunkhash].bundle.js,vendors~a~b.[chunkhash].bundle.js和utilities~a~b.[chunkhash].bundle.js。(译者注:这需要在打包之前,把users.js文件移至./src/utilities目录下,并修改a.js和b.js中的相关引用路径)。虽然我们现在可以让minSize:0成为全局设置(即放在splitChunks对象中作为其属性),但即使这样,默认的缓存组也不会被创建。因为,所有可能被引入的文件都应该在我们刚创建的utilities组下。这个组具的优先级是0,高于默认缓存组的优先级。你可能已经注意到了,默认缓存组的优先级被设置为了-20。
还有其他的配置供你使用,可查看SplitChunksPlugin文档。
总结
即使你只有一个入口(常发生于大多数单页应用中),把你的依赖放入一个独立的文件依然是个好主意。这其实很容易做到,因为使用SplitChunksPlugin是Webpack 4的默认行为,可能你设置一下chunks: 'all'就足够了。如果你想让我讨论此相关话题,欢迎留言。很快我们将会学习如何使用懒加载,让你的应用性能更上一层楼。敬请期待!
Webpack 4教程 - 第四部分,使用SplitChunksPlugin分离代码的更多相关文章
- rabbitMQ教程(四) spring整合rabbitMQ代码实例
一.开启rabbitMQ服务,导入MQ jar包和gson jar包(MQ默认的是jackson,但是效率不如Gson,所以我们用gson) 二.发送端配置,在spring配置文件中配置 <?x ...
- Webpack 4教程 - 第八部分 使用prefetch和preload进行动态加载
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://wanago.io/2018/08/13/webpack-4-course-part ...
- 全网最贴心webpack系列教程和配套代码
webpack-demos:全网最贴心 webpack 系列教程和配套代码 欢迎关注个人技术博客:godbmw.com.每周 1 篇原创技术分享!开源教程(webpack.设计模式).面试刷题(偏前端 ...
- webpack4 系列教程(十四):Clean Plugin and Watch Mode
作者按:因为教程所示图片使用的是 github 仓库图片,网速过慢的朋友请移步<webpack4 系列教程(十四):Clean Plugin and Watch Mode>原文地址.更欢迎 ...
- webpack 使用教程--实时刷新测试
学习webpack,基本始终是围绕: 1.如何安装webpack 2.如何使用webpack 3.如何使用loader 4.如何使用开发服务器 可能我们会在如何使用开发服务器的时候,遇到诸如调试的相关 ...
- [译]MVC网站教程(四):MVC4网站中集成jqGrid表格插件(系列完结)
目录 1. 介绍 2. 软件环境 3. 在运行示例代码之前(源代码 + 示例登陆帐号) 4. jqGrid和AJAX 5. GridSettings 6. ...
- WCF入门教程(四)通过Host代码方式来承载服务
WCF入门教程(四)通过Host代码方式来承载服务 之前已经讲过WCF对外发布服务的具体方式. WCF入门教程(一)简介 Host承载,可以是web,也可以是控制台程序等等.比WebService有更 ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(四):Hello World
============= 以下写于2013-07-20 ============= 这一篇文章其实可以写在很前面,不过我还是希望开发者们尽多地了解清楚原理之后再下手. 通过上一篇Senparc.W ...
- Docker入门教程(四)Docker Registry
Docker入门教程(四)Docker Registry [编者的话]DockerOne组织翻译了Flux7的Docker入门教程,本文是系列入门教程的第四篇,介绍了Docker Registry,它 ...
随机推荐
- linux系统日志查看
系统 日志文件( 可以通过cat 或tail 命令来查看) /var/log/message 系统启动后的信息和错误日志,是Red Hat Linux中最常用的日志之一/var/log/secure ...
- github上传文件的几句命令行
1.首先进入要上传的本地目录,右键打开git命令行. 2.执行指令:git init 初始化本地仓库,这是会看到多了一个.git文件夹(如果没看到那就是电脑隐藏了). 3.执行命令:git ad ...
- 用 fhq_Treap 实现可持久化平衡树
支持对历史版本进行操作的平衡树 Treap 和 Splay 都是旋来旋去的 这样平衡树可持久化听起来不太好搞? 还有 fhq_Treap ! 每次涉及操作就复制一个节点出来 操作历史版本就继承它的根继 ...
- python-----HTMLTestRunner报告生成注意点!
简单的测试加HTMLTestRunner使用的具体方式如下:
- python selenium中Excel数据维护(二)
接着python里面的xlrd模块详解(一)中我们我们来举一个实例: 我们来举一个从Excel中读取账号和密码的例子并调用: ♦1.制作Excel我们要对以上输入的用户名和密码进行参数化,使得这些数据 ...
- 前端ps实用小技巧
下面总结了几个日常使用PS的小技巧,希望对大家有所帮助(重点推荐第一个小技巧) 场景一:用ps测量PSD图中的元素宽高间距时,一般是手动使用 测量,但其实是有快捷键的,如下图 首先选中元素相应图层,然 ...
- numpy C语言源代码调试(一)
近期学习numpy,希望了解numpy内部实现机制,尝试调试numpy的源代码,特别是其中的C语言源码. 在numpy的官方网站上,有numpy的开发人员手册: https://docs.scipy. ...
- 基于Win10极简SonarQube C#代码质量分析
博客有些好些时间未更新了,这几个月的时间里,离开了实习的公司.大学毕了业.来了新公司.转了户口,有点忙,最近总算稍微闲下来了,打算重新拾起博客,坚持写下去. 言归正转,什么是SonarQube ? S ...
- 程序员如何让自己 Be Cloud Native - 配置篇
前言 这是<程序员如何让自己 Be Cloud Native>系列文章的第二篇,从第一篇的反馈来看,有些同学反馈十二要素太形式主义,不建议盲目跟从.作者认为任何理论和技术都需要有自己的观点 ...
- 5.3Role和Claims授权「深入浅出ASP.NET Core系列」
希望给你3-5分钟的碎片化学习,可能是坐地铁.等公交,积少成多,水滴石穿,码字辛苦,如果你吃了蛋觉得味道不错,希望点个赞,谢谢关注. Role授权 这是一种Asp.Net常用的传统的授权方法,当我们在 ...