前段时间一直在基于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. day20 GUI(Graphics User Interface)

    顶层容器:JWindow.JFrame.JDialge.JAsplet JFrame,默认布局是边界布局 JFrame的内容面板是:Container. 面板容器:JPanel,默认布局是流布局. 布 ...

  2. day16 常用类(String、StringBuffer、StringBuilder)

    1.String是唯一一个可以直接用常量赋值的引用数据类型. String的常量也是一个对象. 数据段——字符串常量池. 2.每一个字符串常量对象在加载期放入字符串常量池. java对String常量 ...

  3. 科学计算三维可视化---TVTK管线与数据加载(用IVTK根据观察管线)

    一:用IVTK根据观察管线 (一)引入该工具 from tvtk.tools import ivtk 可能需要安装pygments pip3 install pygments (二)使用ivtk显示立 ...

  4. ActiveMQ基本详解与总结& 消息队列-推/拉模式学习 & ActiveMQ及JMS学习

    转自:https://www.cnblogs.com/Survivalist/p/8094069.html ActiveMQ基本详解与总结 基本使用可以参考https://www.cnblogs.co ...

  5. 1130 N的阶乘的长度 V2(斯特林近似)

    1130 N的阶乘的长度 V2(斯特林近似) 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 输入N求N的阶乘的10进制表示的长度.例如6! = 720, ...

  6. Jenkins maven 构建乱码,修改file.encoding系统变量编码为UTF-8

    一切都是windows的控制台默认编码GBK问题 情景: 使用jenkins构建,console 输出的中文乱码.代码编码格式是utf-8,因为Jenkins会默认读取当前系统的编码格式,导致构建日志 ...

  7. GitHub更新已经fork的项目

    clone 自己的 fork 分支到本地 可以直接使用 GitHub 客户端,clone 到本地,如果使用命令行,命令为: $ git clone git@github.com:morethink/g ...

  8. Fiddler 使用

    一.模拟post请求 User-Agent: FiddlerContent-Type: application/json; charset=utf-8Content-Length: 138Conten ...

  9. 样式缩写——css技巧(一)

    一.margin和padding缩写 例: .sample-margin1{ margin-top:15px; margin-right:20px; margin-bottom:12px; margi ...

  10. url添加时间戳

    http://blog.csdn.net/qq_36769100/article/details/54564784 URL后面添加随机数通常用于防止客户端(浏览器)缓存页面. 浏览器缓存是基于url进 ...