前段时间一直在基于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打包优化的更多相关文章

  1. Webpack 打包优化之速度篇

    在前文 Webpack 打包优化之体积篇中,对如何减小 Webpack 打包体积,做了些探讨:当然,那些法子对于打包速度的提升,也是大有裨益.然而,打包速度之于开发体验和及时构建,相当重要:所以有必要 ...

  2. Webpack 打包优化之体积篇

    谈及如今欣欣向荣的前端圈,不仅有各类框架百花齐放,如Vue, React, Angular等等,就打包工具而言,发展也是如火如荼,百家争鸣:从早期的王者Browserify, Grunt,到后来赢得宝 ...

  3. (webpack系列二)webpack打包优化探索

    虽然webpack的已经升级到了webpack4,而我们目前还在使用webpack3,但其中的优化点都大同小异,升级后同样适用. 性能优化初步原则 减小代码量 减小请求数 最大化利用浏览器缓存 这三条 ...

  4. webpack打包优化之外部扩展externals的实际应用

    目录 前言 externals定义 用法 string array object function regex 实际案例 打包时间 打包之后包的大小 浏览器加载 需要注意 参考 前言 使用vue-cl ...

  5. 记一次webpack打包优化

    未进行打包优化的痛点: 随着项目的不断扩大,引入的第三方库会越来越多,我们每次build的时候会对所有的文件进行打包,耗时必定很长,不利于日常开发. 解决思路: 第三方库我们只是引入到项目里来,一般不 ...

  6. [转] Webpack 打包优化之体积篇

    谈及如今欣欣向荣的前端圈,不仅有各类框架百花齐放,如Vue, React, Angular等等,就打包工具而言,发展也是如火如荼,百家争鸣:从早期的王者Browserify, Grunt,到后来赢得宝 ...

  7. webpack打包优化并开启gzip

    应用场景:项目使用webpack2.x进行打包,打包后静态资源通过nginx转发配置: 问题:webpack打包后的资源文件特别,特别大,没打包之前页面一个页面js有2M左右(其中已经抽离了css)? ...

  8. webpack 打包优化的四种方法(多进程打包,多进程压缩,资源 CDN,动态 polyfill)

    如今,webpack 毫无疑问是前端构建领域里最耀眼的一颗星,无论你前端走哪条路线,都需要有很强的webpack 知识.webpack 的基本用法这里就不展开讲了.主要探讨一下如何提高 webpack ...

  9. webpack打包优化点

    目录 1. noParse 2. 包含和排除目录 3. IgnorePlugin 4. happypack 5. DllPlugin动态链接库 6. 热更新 7. 开发环境 tree-shaking ...

随机推荐

  1. Docker swarm 使用服务编排部署lnmp

    一.简介 目的:在Docker Swarm集群中,使用stack服务编排搭建lnmp来部署WordPress 使用私有仓库的nginx和php镜像 mysql使用dockerhup最新镜像 使用nfs ...

  2. css基础--简单介绍css

    --引入 什么是css? CSS 指层叠样式表 (Cascading Style Sheets) 样式定义如何显示 HTML 元素 样式通常存储在样式表中 把样式添加到 HTML 4.0 中,是为了解 ...

  3. 用Anaconda安装本地python包

    Anaconda确实带来了很多方便,但是之前也过多的依赖了conda自带的一键下载python包的功能.这不,这几天突然要用FastFM这个包,无奈conda里没有,于是只能从github下载下来,实 ...

  4. vue 混入的理解

  5. PHP常亮

    define('PI','3.14'); echo PI; 名字大写,创建后不能修改和销毁 销毁变量用unset()

  6. NO.11天作业

    打印uid在30~40范围内的用户名.awk -F: '$3>=30 && $3<=40{print $1,$3}' /etc/passwd 打印第5-10行的行号和用户名 ...

  7. git使用初探

    1.创建文件夹,初始化git 比如在 E:\Study\xuexixuexi\guns 下创建一个guns的文件夹 使用cmd进入该文件夹:输入git init git init 2.添加远程仓库: ...

  8. CF&&CC百套计划3 Codeforces Round #204 (Div. 1) A. Jeff and Rounding

    http://codeforces.com/problemset/problem/351/A 题意: 2*n个数,选n个数上取整,n个数下取整 最小化 abs(取整之后数的和-原来数的和) 先使所有的 ...

  9. [转载]代码编辑器Sublime Text 3 免费使用方法与简体中文汉化包下载

    http://devework.com/sublime-text-3.html Sublime Text这款代码编辑器是Jeff 一直都在使用的,前段时间转用到版本3,因为感觉Sublime Text ...

  10. 《java语言程序设计》初步学习——各种小Demo

    发现现在的天下几乎都是java的天下啊,虽然我个人对java没什么好感,但是迫于生活压力,还是学一下吧,我关注的应该主要还是web方面,所以应该学的是 java server page(JSP),所以 ...