webpack 动态entry-了解 webpack 中代码分割的一站式解决方案

2024-02-13 0 4,439 百度已收录

最后分析发现sourcemap是通过devtool配置项设置的。 在线环境下,可以通过设置成cheap-module-source-map来生成单独的map文件。 但是在线环境下每次都会加载地图文件吗? 如果加载的话会不会造成带宽和请求的浪费?

笔者也有这样的疑问,于是就上网查了一下。 后来了解到,在浏览器中,只能在调试模式下手动下载地图文件。 在正常的上网环境下,无需担心这个问题。

为什么使用 webpack 构建单页面应用程序时需要进行代码分割?

如果入口中只配置了一个入口,那么如果从这个入口文件引入的公共库的代码太大,那么打包时只会有一个bundle文件。 当浏览器加载这样一个过大的bundle时,会导致加载缓慢。

一般来说,我们的公共图书馆代码不会时常改变。 然而我们的业务代码经常需要改动。 如果打包成不同的bundle文件,我们就可以更好的利用浏览器的缓存,在浏览器端复用公共库之前的bundle文件。

那么如何通过代码分割来优化呢?

webpack 3 中可以通过 CommonsChunkPlugin 来完成代码分割,但是在 webpack 4 中,官方提倡使用 SplitChunksPlugin 插件,所以本文主要讲解如何在 webpack 4 中通过 SplitChunksPlugin 插件实现代码分割。

首先我们要先明确一个初步的知识点,那就是在webpack中,什么叫chunk,什么叫bundle?

下面的图片可以帮助我们更好的理解:

webpack打包配置条目中有两个条目:index和utils。 分别对应index.js文件和utils.js文件,其中index.js文件引用了common.js和index.css。 那么webpack打包的时候会以前三个文件作为一个chunk,然后将utils.js文件作为一个chunk。 但在webpack配置中,使用了MiniCssExtractPlugin插件来提取css文件,因此形成了两个.css和.js。 捆绑文件。 简而言之,chunk是webpack打包时的一个概念,形成的单个文件在浏览器中运行时可以称为bundle。

其实上面webpack配置文件中两个条目的配置,其中utils全局挂载了一些工具功能,也可以看作是一种代码切割,但是有没有更灵活的形式呢? 我们来看看 SplitChunksPlugin 插件。

SplitChunksPlugin插件的介绍可以在webpack的官方文档中找到:

从文档中可以看到SplitChunksPlugin的默认配置如下:

下面会一点一点的解释。

代码拆分有两种场景:一种是同步引入的代码模块的拆分,一种是异步引入的代码模块的拆分。

1.同步代码分割:

在业务代码中引入lodash,通过前面提到的webpack-bundle-analyzer插件分析打包情况如下:

可以看到我们的src文件和node_modules文件都在一个bundle中。 如果我们想将node_module中的库文件单独打包成一个chunk,可以将官网SplitChunksPlugin的默认配置复制到打包配置文件中,然后进行如下修改:

其中chunks表示可以配置为initial、async、all,分别代表静态引入、动态引入、代码分割这两种情况。

minSize是可以进行代码分割的最小包大小,默认为30000Byte。 在打包分析中,我们看到lodash经过webpack处理后的打包体积接近70KB,大于SplitChunksPlugin的最小打包体积。 所以进行上述修改后,lodash就可以打包成一个单独的chunk了。 打包后情况如下:

从图中我们可以看到lodash被单独打包成一个名为vendors~index.js的chunk。

接下来我们来设置一下里面分析的打包流程。 满足minSize条件后,您可以按照条件进行cacheGroups配置。 cacheGroups 中有不同的对象。 对象中的测试就是测试规律。 当引用的模块名称满足这条测试规则后,就会按照当前对象的规则进行打包。

键名vendors是包的前缀名,automaticNameDelimiter中配置的是前缀旁边的连接符,后面是引入该模块的条目中配置的条目文件名索引。

如果我们想自定义lodash打包的文件名,可以将vendors中的文件名配置为vendors.js,如下:

然后打包好的lodash chunk称为vendors.js,cacheGroups上面的name:true表示让cacheGroups中的文件名生效。

接下来我们介绍splitChunks中剩下的配置:

minChunk 是什么意思? 他的意思是表项中配置的表项指的是模块的最小编号。 只有当至少有 minChunks 个 chunk 引用当前模块时,才会单独打包。

maxAsyncRequests表示代码拆分后可以同时发出的最大请求数。

maxInitialRequests 表示首页的最大请求数。 如果代码拆分后首页请求的请求数小于此数量webpack 动态entry,则代码拆分不会继续。

2.异步代码分割:

你可能对异步加载的句型不是很熟悉。 你可以在官网API部分找到import异步加载的句型描述。 它实际上是ES6的一个句型:

在webpack的使用中,webpack通过一个叫做“神奇注解”的功能来丰富打包功能,下面会详细听到。

在 webpack 中,SplitChunksPlugin 默认会对异步导入的代码进行拆分,但是为了支持异步导入模块的句型,我们还是需要安装 babel 的 plugin-syntax-dynamic-import 插件来支持异步加载句型。

我们来详细看看我们的业务代码:

在index.js中webpack 动态entry,我们通过click事件动态引入了handleClick.js文件。 带注释的部分使用魔术注释来命名划分的块handleClick。

在handleClick.js文件中,我们向文档添加元素(process.env.NODE_ENV是运行时环境变量,可以参考之前的推送)。

从下面的运行结果可以看出,当网页刷新时,首先加载的是index.html文件和index.js文件。 点击网页时,会请求handleClick.js文件,网页上会出现“123”。

事实上,异步代码分割还有一个你可能更熟悉的名字——延迟加载。

但是,如果异步加载的模块很大,我们在实际项目中完成操作后临时请求,加载是否还会很慢? 为了解决这个问题,可以在magic注解中使用webpackPrefetch,让浏览器在加载完首页的js文件后空闲时加载异步分割的bundle文件。

参考:

#标题-15

#中=22363

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 webpack webpack 动态entry-了解 webpack 中代码分割的一站式解决方案 https://www.wkzy.net/game/200178.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务