基于CommonsChunkPlugin,webpack打包优化
前段时间一直在基于webpack进行前端资源包的瘦身。在项目中基于路由进行代码分离,http://www.cnblogs.com/legu/p/7251562.html。但是打包的文件还是很大,特别是通过CommonsChunkPlugin的async:true打包的chunk的公共包不可控。今天就通过CommonsChunkPlugin插件的理解,来优化这个问题
问题描述详细些,我们的打包是基于router进行的chunk分割,比如router有10个,router1,router2用到了echart,所以echart打包到了公共文件async中。但是如果用户通过链接,
第一次直接访问的router3,这样就会先加载公共文件async,可是echart代码其实是多余的,影响到了router3的展现。
一开始遇到这个问题,没想到太好的方法,让echart基于chunk进行按需打包~~实在没办法,最后只能从CommonsChunkPlugin插件的源代码入手,看看有什么启发。
apply(compiler) {
compiler.plugin("this-compilation", (compilation) => {
compilation.plugin(["optimize-chunks", "optimize-extracted-chunks"], (chunks) => {
/**
* 根据chunkNames[options.name, options.names],从chunks中筛选出targetChunks, 没有则使用compilation.addChunk新增
* 如果children || async,返回targetChunks = chunks
*/
const targetChunks = this.getTargetChunks(chunks, compilation, this.chunkNames, this.children, this.async);
targetChunks.forEach((targetChunk, idx) => {
/**
* 根据selectedChunks【options.chunks】,从chunks筛选出affectedChunks
* async || children,返回 affectedChunks = targetChunk.chunks, 如果children = true,进行深度遍历
*/
const affectedChunks = this.getAffectedChunks(compilation, chunks, targetChunk, targetChunks, idx, this.selectedChunks, this.async, this.children, this.deepChildren);
let asyncChunk;
if(this.async) {
//如果async==string,进行name筛选
asyncChunk = affectedChunks.filter(c => c.name === this.async)[0];
if(!asyncChunk) {
/**
* 根据async创建一个新的chunk,和targetChunk绑定关系
* asyncChunk.addParent(targetChunk); targetChunk.addChunk(asyncChunk);
*/
asyncChunk = this.createAsyncChunk(
compilation,
targetChunks.length <= 1 || typeof this.async !== "string" ? this.async :
targetChunk.name ? `${this.async}-${targetChunk.name}` :
true,
targetChunk
);
}
targetChunk = asyncChunk;
}
// 根据minChunks的设置,遍历affectedChunks的modules,返回符合条件的公共modules集合
const extractableModules = this.getExtractableModules(this.minChunks, affectedChunks, targetChunk);
if(this.minSize) {// minSize限制逻辑
const modulesSize = this.calculateModulesSize(extractableModules);
if(modulesSize < this.minSize)
return;
}
// affectedChunks中移除extractableModules中modules的关系,只返回存在公共modules的Chunks集合(removeChunk返回true)
const chunksWithExtractedModules = this.extractModulesAndReturnAffectedChunks(extractableModules, affectedChunks);
// 公共的modules 和 targetChunk 绑定关联关系
// chunk.addModule(module); module.addChunk(chunk);
this.addExtractedModulesToTargetChunk(targetChunk, extractableModules);
if(this.filenameTemplate)
targetChunk.filenameTemplate = this.filenameTemplate;
if(this.async) {
//被移除modules的Chunk,设置和targetChunk的关系,需要第一个加载targetChunk才能加载chunksWithExtractedModules
this.moveExtractedChunkBlocksToTargetChunk(chunksWithExtractedModules, targetChunk);
asyncChunk.origins = this.extractOriginsOfChunksWithExtractedModules(chunksWithExtractedModules);
return;
}
//设置affectedChunks和targetChunk的parent关系
this.makeTargetChunkParentOfAffectedChunks(affectedChunks, targetChunk);
});
return true;
});
});
}
代码逻辑不是很复杂,主要是chunks之间的关系和chunks与modules之间的关系该怎么去维护,对于不清楚webpack打包机制的人,很难一时间了解。其实我也不很了解。
根据上面我的中文注释,对大家的了解有一些帮助。我们会发现,对我们的问题没有什么直接关系。
回到我们的问题,异步的模块中,共用模块怎么能再进行拆分,把大模块echarts,ace编辑器等进行分开打包,并且能自己处理关系,需要的时候才异步加载进来?
其实最后问题的答案很简单,需要实现自动异步加载,那肯定还是要借助CommonsChunkPlugin的async,我们可以根据实际情况,通过minChunks,把echarts,ace这种大库先进行一次async打包,这样再进行根据router的async打包的时候,自然不会再有echarts,ace了,看下现在的配置
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'libs', 'manifest']
}),
new webpack.optimize.CommonsChunkPlugin({
async: 'brace',
minChunks: function(module, count) {
var path = `/public/node_modules`;
var resource = module.resource;
if ( resource &&
(
resource.indexOf(`${path}/_brace`) !== -1 ||
resource.indexOf(`${path}/brace`) !== -1
)
) {
return true
}
return false;
}
}),
new webpack.optimize.CommonsChunkPlugin({
async: 'echarts',
minChunks: function(module, count) {
var path = `/public/node_modules`;
var resource = module.resource;
if ( resource &&
(
module.resource.indexOf(`${path}/_echarts`) !== -1 ||
module.resource.indexOf(`${path}/echarts`) !== -1 ||
module.resource.indexOf(`${path}/zrender`) !== -1 ||
module.resource.indexOf(`${path}/_zrender`) !== -1
)
) {
return true
}
return false;
}
}),
new webpack.optimize.CommonsChunkPlugin({
async: 'async',
minChunks: 2
}),
基于CommonsChunkPlugin,webpack打包优化的更多相关文章
- Webpack 打包优化之速度篇
在前文 Webpack 打包优化之体积篇中,对如何减小 Webpack 打包体积,做了些探讨:当然,那些法子对于打包速度的提升,也是大有裨益.然而,打包速度之于开发体验和及时构建,相当重要:所以有必要 ...
- Webpack 打包优化之体积篇
谈及如今欣欣向荣的前端圈,不仅有各类框架百花齐放,如Vue, React, Angular等等,就打包工具而言,发展也是如火如荼,百家争鸣:从早期的王者Browserify, Grunt,到后来赢得宝 ...
- (webpack系列二)webpack打包优化探索
虽然webpack的已经升级到了webpack4,而我们目前还在使用webpack3,但其中的优化点都大同小异,升级后同样适用. 性能优化初步原则 减小代码量 减小请求数 最大化利用浏览器缓存 这三条 ...
- webpack打包优化之外部扩展externals的实际应用
目录 前言 externals定义 用法 string array object function regex 实际案例 打包时间 打包之后包的大小 浏览器加载 需要注意 参考 前言 使用vue-cl ...
- 记一次webpack打包优化
未进行打包优化的痛点: 随着项目的不断扩大,引入的第三方库会越来越多,我们每次build的时候会对所有的文件进行打包,耗时必定很长,不利于日常开发. 解决思路: 第三方库我们只是引入到项目里来,一般不 ...
- [转] Webpack 打包优化之体积篇
谈及如今欣欣向荣的前端圈,不仅有各类框架百花齐放,如Vue, React, Angular等等,就打包工具而言,发展也是如火如荼,百家争鸣:从早期的王者Browserify, Grunt,到后来赢得宝 ...
- webpack打包优化并开启gzip
应用场景:项目使用webpack2.x进行打包,打包后静态资源通过nginx转发配置: 问题:webpack打包后的资源文件特别,特别大,没打包之前页面一个页面js有2M左右(其中已经抽离了css)? ...
- webpack 打包优化的四种方法(多进程打包,多进程压缩,资源 CDN,动态 polyfill)
如今,webpack 毫无疑问是前端构建领域里最耀眼的一颗星,无论你前端走哪条路线,都需要有很强的webpack 知识.webpack 的基本用法这里就不展开讲了.主要探讨一下如何提高 webpack ...
- webpack打包优化点
目录 1. noParse 2. 包含和排除目录 3. IgnorePlugin 4. happypack 5. DllPlugin动态链接库 6. 热更新 7. 开发环境 tree-shaking ...
随机推荐
- Unity官方实例教程 Roll-a-Ball
与unity的transform组件相处的挺久了,最近项目不太忙,决定好好打下unity的基础.那么从Roll-a-Ball这个简单游戏开始吧! 1.先创建一个球体游戏对象,改名为Player,tra ...
- Java基础-数组常见排序方式
Java基础-数组常见排序方式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 数据的排序一般都是生序排序,即元素从小到大排列.常见的有两种排序方式:选择排序和冒泡排序.选择排序的特 ...
- 秋色园QBlog技术原理解析:性能优化篇:缓存总有失效时,构造持续的缓存方案(十四)
转载自:http://www.cyqdata.com/qblog/article-detail-38993 文章回顾: 1: 秋色园QBlog技术原理解析:开篇:整体认识(一) --介绍整体文件夹和文 ...
- 2018年9月22日CCPC吉林站参赛总结
发现思维题是硬伤,代码能力是硬伤,对知识点的理解不深刻是硬伤 接下来要做的就是 1.熟悉每一个知识点,把每一个知识点和实现它的代码联系在一起学习 2.多见题,看看他们是怎么考察这些知识点的,等比赛的时 ...
- 动态规划:POJ No 2385 Apple Catching
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> ...
- zz图像卷积与滤波的一些知识点
Xinwei: 写的通俗易懂,终于让我这个不搞CV.不搞图像的外行理解卷积和滤波了. 图像卷积与滤波的一些知识点 zouxy09@qq.com http://blog.csdn.net/zouxy09 ...
- 博主退役了qwq
noip靠太差的(蒟蒻)博主退役了qwq 感觉以后都没什么机会可以继续写博客了 这个博客八成是坟了呀qwq 其实感觉也没有什么人关注qwq 所以也不长篇大论些什么了 就这样吧qwq
- 连接mysql提示Establishing SSL connection without server's identity verification is not recommended错误
Establishing SSL connection without server's identity verification is not recommended. According to ...
- 汇编与C语句
---恢复内容开始--- 汇编与C语句 4.1C语句与汇编 学习了汇编语言之后,就需要将常用的C语言代码结构与相应的汇编语言联系起来.这样就可以在分析汇编语言的时候,明白它的意思.C语言中函数过程的调 ...
- Nginx服务优化详解
Nginx服务优化详解 1.隐藏Nginx版本信息 编辑主配置文件nginx.conf,在http标签中添加代码 server_tokens off;来隐藏软件版本号. 2.更改Nginx服务启动的默 ...