webpack4【guides说明6】

接下来是webpack的code splitting部分

code splitting 是webpack最有特色的特征之一。这个特性使你可以分割你的代码进不同的“包”中,然后这些个被切割的包可以按需加载或者并行加载,这样就可以达到更小的包(代码块),以及控制资源加载优先级,如果应用得当,可能对页面的加载时间会有巨大的影响。

通常有3中机制来有效分割代码:

1.入口点:通过使用entry项,可以在顶层的角度将项目分割成多个大的包

2:防止冗余代码:使用SplitChunksPlugin 来去除可能存在的冗余代码,达到代码分块的效果。

3:动态引入:通过模块内内联函数的调用,达到代码分割。

 

先说说配置多个entry point,这是目前最直观的分割代码的方式。然而,这种方式更手工化配置多入口,以及它还有一些缺点,下面慢慢道来。

重新清理项目目录

 

 

创建新的模块,更新webpack.config.js,entry配置,并且留意到another-module.js 和 index.js同时引用了lodash,看看会发生什么,类似这种情况在实际开发中也是会经常遇见的。

打包后,在生成的2个bundle文件中去搜索一下lodash看看会搜到什么

目前webpack.config.js mode配置的是development,可以看见,在两个都使用到了lodash模块的时候,lodash被2次打包到生成的2个包文件中去了。这就造成了代码冗余,本来需要一份lodash代码即可的,现在多出了1分,然后实际中可能是n个entry,n份lodash.

..

为了解决,但是不局限于entry point留下来的多份冗余代码的问题,于是有了下面的防冗余处理

SplitChunksPlugin让我们可以抽取通用依赖项到一个已存在的entry chunks(打包生成的文件,这是我的理解)又或者是一个全新的chunk。接下来让我们使用这个插件来解决冗余的lodash依赖问题。

CommonsChunkPlugin已经在webpack4中移除,想知道新版本webpack是怎么处理chunks的,可以查阅SplitChunksPlugin说明。

而这个插件不需要安装的,直接配置webpack.config.js文件即可

通过使用optimization.splitChunks配置项,我们现在发现冗余的依赖项不存在于index.bundle.js和another.bundle.js中了。插件已经识别了,我们想要将lodash移到一个独立的chunk中去了,以减少生成的bundle文件的体积。

运行打包命令后

搜索bundle文件,发现原先的lodash文件代码不存在了,只剩下一些桩代码

这样一来,依赖项冗余解决了。至于如何配置optimization.chunks则不介绍了,自己可以去试试。

做最后还介绍了3个分割代码的插件或者loader

第一个是用来抽取公共css的,//todo

第二个用来懒加载公共模块的loader,//todo

第三个是使用promise来懒加载公共模块的 //todo

 

最后是动态引入

webpack支持2种相似的方式来动态引用。第一种是推荐的方式:使用import()语法,这符合ecmascript 动态引用的提议。第二种,也是比较过时的webpack独有的使用 require.ensure方式。

import()内部,使用promise,因此对于那些可能不支持promise的浏览器是需要使用promose-polyfill预先处理的。

更新配置文件,去掉防冗余,多入口的配置:

 

此处不配置output.chunkFilename字段,打完包后发现项目结构如下:

留下几个问题

1.对比防冗处理时产生的chunk文件名和此次产生的chunk名,

2对比index.html引用的脚本

引入一个app.bundle.js文件,却又2个js请求。说明index.html文件加载完app.bundle.js后,app.bundle.js文件又会自动加载app.js文件,这样做就是将原来2部分串行加载的代码的方式 变成先加载主模块,然后,在主模块相关代码执行时异步加载所需模块的方式,好处自然是降低了页面初始加载数据,以及响应时间了。

 

在index.js中,

function getComponent() {

    return import(/* webpackChunkName: "lodash" */ 'lodash').then(({ default: _ }) => {
        const element = document.createElement('div');

        element.innerHTML = _.join(['Hello', 'webpack'], ' ');

        return element;

    }).catch(error => 'An error occurred while loading the component');
}

注意到注释中的webpackChunkName,结合output.chunkFilename,(默认是[name].bundle.js形式)生成chunk文件名。

修改配置和index.js文件如下,试看看

 

对于其他import()选项 参考 import() documentation.

至于为什么会有个default解构,是因为从webpack4开始,当引入一个commonJS模块时import不再直接解析到 该模块的module.exports去了,而是会创建一个命名空间(一个对象),包含该模块(一个匿名obj的default属性,这也就说明了解构到default的由来)。背后的理由,请查阅webpack 4: import() and CommonJs

 

既然import()返回一个promise,那么久可以用async function的方式处理了

 

更为灵活的是,import()支持表达式动态加载。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值