webpack多页应用架构系列(三):怎么打包公共代码才能避免重复?

本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。
原文地址:https://segmentfault.com/a/1190000006871991
如果您对本系列文章感兴趣,欢迎关注订阅这里:https://segmentfault.com/blog/array_huang

前言

与单页应用相比,多页应用存在多个入口(每个页面即一个入口),每一个入口(页面)都意味着一套完整的js代码(包括业务逻辑和加载的第三方库/框架等)。
在上一篇文章(webpack多页应用架构系列(二):webpack配置常用部分有哪些?)中,我介绍了如何配置多页应用的入口(entry),然而,如果仅仅如此操作,带来的后果就是,打包生成出来的每一个入口文件都会完整包含所有代码。
你也许会说:"咱们以前写页面不也是每个页面都会加载所有的代码吗?浏览器会缓存,没事的啦"。其实问题在于,以前写代码都是单个单个js来加载的,一个页面加载下来的确所有页面都能共享到缓存;而到了webpack这场景,由于对于每一个页面来说,所有的js代码都打包成唯一一个js文件了,而浏览器是无法分辨出该文件内的公共代码并加以缓存的,所以,浏览器就没办法实现公共代码在页面间的缓存了(当前页面的缓存还是OK的,也就是说刷新不需要重新加载)。

想智能判断并打包公共代码?CommonsChunkPlugin能帮到你

CommonsChunkPlugin的效果是:在你的多个页面(入口)所引用的代码中,找出其中满足条件(被多少个页面引用过)的代码段,判定为公共代码并打包成一个独立的js文件。至此,你只需要在每个页面都加载这个公共代码的js文件,就可以既保持代码的完整性,又不会重复下载公共代码了(多个页面间会共享此文件的缓存)。

再提一下使用Plugin的方法

大部分Plugin的使用方法都有一个固定的套路:

  1. 利用Plugin的初始方法并传入Plugin预设的参数进行初始化,生成一个实例。
  2. 将此实例插入到webpack配置文件中的plugins参数(数组类型)里即可。

CommonsChunkPlugin的初始化常用参数有哪些?

  • name,给这个包含公共代码的chunk命个名(唯一标识)。
  • filename,如何命名打包后生产的js文件,也是可以用上[name][hash][chunkhash]这些变量的啦(具体是什么意思,请看我上一篇文章中关于filename的那一节)。
  • minChunks,公共代码的判断标准:某个js模块被多少个chunk加载了才算是公共代码。
  • chunks,表示需要在哪些chunk(也可以理解为webpack配置中entry的每一项)里寻找公共代码进行打包。不设置此参数则默认提取范围为所有的chunk。

实例分析

实例来自于我的脚手架项目webpack-seed,我是这样初始化一个CommonsChunkPlugin的实例:

  var commonsChunkPlugin = new webpack.optimize.CommonsChunkPlugin({
    name: 'commons', // 这公共代码的chunk名为'commons'
    filename: '[name].bundle.js', // 生成后的文件名,虽说用了[name],但实际上就是'commons.bundle.js'了
    minChunks: 4, // 设定要有4个chunk(即4个页面)加载的js模块才会被纳入公共代码。这数目自己考虑吧,我认为3-5比较合适。
  });

最终生成文件的路径是根据webpack配置中的ouput.path和上面CommonsChunkPlugin的filename参数来拼的,因此想控制目录结构的,直接在filename参数里动手脚即可,例如:filename: 'commons/[name].bundle.js'

总结

整体来说,这套方案还是相当简单的,而从效果上说,也算是比较均衡的,比较适合项目初期使用。最近我也得到了打包公共代码的其它思路,相对于本文来说算是进阶版的吧,但是维护成本相对应也提高了,待我试用后再写文介绍给大家。

示例代码

诸位看本系列文章,搭配我在Github上的脚手架项目食用更佳哦(笑):Array-Huang/webpack-seed(https://github.com/Array-Huang/webpack-seed)。

附系列文章目录(同步更新)

  • webpack多页应用架构系列(一):一步一步解决架构痛点
  • webpack多页应用架构系列(二):webpack配置常用部分有哪些?
  • webpack多页应用架构系列(三):怎么打包公共代码才能避免重复?
  • webpack多页应用架构系列(四):老式jQuery插件还不能丢,怎么兼容?
  • webpack多页应用架构系列(五):听说webpack连less/css也能打包?
  • webpack多页应用架构系列(六):听说webpack连图片和字体也能打包?
  • webpack多页应用架构系列(七):开发环境、生产环境傻傻分不清楚?
  • webpack多页应用架构系列(八):教练我要写ES6!webpack怎么整合Babel?
  • webpack多页应用架构系列(九):总有刁民想害朕!ESLint为你阻击垃圾代码
  • webpack多页应用架构系列(十):如何打造一个自定义的bootstrap
  • webpack多页应用架构系列(十一):预打包Dll,实现webpack音速编译
  • webpack多页应用架构系列(十二):利用webpack生成HTML普通网页&页面模板
  • webpack多页应用架构系列(十三):构建一个简单的模板布局系统
  • webpack多页应用架构系列(十四):No复制粘贴!多项目共用基础设施
  • webpack多页应用架构系列(十五):论前端如何在后端渲染开发模式下夹缝生存

本文首发于Array_Huang的技术博客——实用至上,非经作者同意,请勿转载。
原文地址:https://segmentfault.com/a/1190000006871991
如果您对本系列文章感兴趣,欢迎关注订阅这里:https://segmentfault.com/blog/array_huang

你可能感兴趣的:(webpack多页应用架构系列(三):怎么打包公共代码才能避免重复?)