webpack学习-5.代码分离

webpack学习-5.代码分离

  • 1.入口起点
  • 2.防止重复
    • 2.1 入口依赖
    • 2.2 SplitChunksPlugin
  • 3.动态导入
    • 3.1 使用符合 ECMAScript 提案 的 import() 语法
    • 3.2 使用 webpack 特定的 require.ensure
  • 4.预获取/预加载模块
  • 5.分析bundle
  • 6.总结

1.入口起点

代码分离是 webpack 中最引人注目的特性之一。此特性能够把代码分离到不同的 bundle 中,然后便能按需加载或并行加载这些文件。代码分离可以用于获取更小的 bundle、控制资源加载优先级,如果使用合理,会极大减小加载时间。
常用的代码分离方法有三种:

入口起点:使用 entry 配置手动地分离代码。
防止重复:使用 入口依赖 或者 SplitChunksPlugin 去重和分离 chunk。
动态导入:通过模块的内联函数调用分离代码。

入口起点,这是迄今为止最简单直观的实现代码分离的方式。不过,这种方式手动配置较多,并有一些隐患。不过,我们将会介绍如何解决这些隐患。先来看看如何从 main bundle 中分离另一个模块:
项目目录结构:
在这里插入图片描述
其他跟着官网例子来。这种方式存在一些隐患:

1.如果入口 chunk 之间包含一些重复的模块,那么这些重复模块会被引入到各个 bundle 中。(例子中的两个js文件都引入了lodash)
2.这种方法不够灵活,并且不能动态地拆分应用程序逻辑中的核心代码。(后面没怎么懂暂时)

以上两点中,第一点所对应的问题已经在我们上面的实例中体现出来了。除了 ./src/another-module.js,我们也曾在 ./src/index.js 中引入过 lodash,这就导致了重复引用。

2.防止重复

2.1 入口依赖

在配置文件中配置 dependOn 选项,以在多个 chunk 之间共享模块:

 const path = require('path');module.exports = {mode: 'development',entry: {index: {import: './src/index.js',dependOn: 'shared',},another: {import: './src/another-module.js',dependOn: 'shared',},shared: 'lodash',},output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},};

如果想要在一个 HTML 页面上使用多个入口起点,还需设置 optimization.runtimeChunk: ‘single’,否则会遇到 此处 所述的麻烦。
我们这里是多入口起点,所以要设置:

 const path = require('path');module.exports = {mode: 'development',entry: {index: {import: './src/index.js',dependOn: 'shared',},another: {import: './src/another-module.js',dependOn: 'shared',},shared: 'lodash',},output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),},optimization: {runtimeChunk: 'single',},};

构建结果如下:
在这里插入图片描述
可以看到,除了 shared.bundle.js,index.bundle.js 和 another.bundle.js 之外,还生成了一个 runtime.bundle.js 文件。

存在四个打包文件的原因如下:

index.js 和 another-module.js 分别作为两个独立的入口点(index 和another)进行打包,因此会生成两个对应的 bundle 文件。
lodash 被指定为共享的依赖模块(shared),Webpack将其提取到一个单独的共享块中。
此外,Webpack 还会生成一个额外的运行时文件,其中包含了模块加载和执行的逻辑。

因此,根据上述配置,最终会生成四个打包文件:

index.js:包含 ./src/index.js 的代码。
another.js:包含 ./src/another-module.js
的代码。 shared.js:包含 lodash 的代码。
runtime.js:包含 Webpack 运行时代码。

这种是可以将重复的依赖防止重复的,但是我就还不清楚重复的依赖在哪个文件里了暂时。

尽管 webpack 允许每个页面使用多个入口起点,但在可能的情况下,应该避免使用多个入口起点,而使用具有多个导入的单个入口起点:entry: { page: [‘./analytics’, ‘./app’] }。这样可以获得更好的优化效果,并在使用异步脚本标签时保证执行顺序一致。
(这句话的意思是,尽管 Webpack 允许在配置中使用多个入口起点,但在可能的情况下,最好使用具有多个导入的单个入口起点,以获得更好的优化效果并确保异步脚本标签的执行顺序一致。

在 Webpack 中,每个入口起点都会生成一个输出文件,这意味着如果你使用多个入口起点,就会生成多个输出文件。这种情况下,每个输出文件都需要加载并执行,会增加额外的网络请求和加载时间。

相比之下,使用具有多个导入的单个入口起点可以将所有的代码逻辑打包到一个输出文件中,从而减少了网络请求和加载时间。这样可以提高应用程序的性能和加载速度。

另外,当你使用异步脚本标签(

而当你使用具有多个导入的单个入口起点时,所有的代码逻辑都被打包到一个输出文件中,保证了代码的执行顺序一致性,避免了潜在的依赖问题。

因此,为了获得更好的优化效果和保证执行顺序的一致性,建议在可能的情况下使用具有多个导入的单个入口起点。

需要注意的是,这并不是绝对的规则,而是在一般情况下的最佳实践。在某些特殊情况下,使用多个入口起点可能是合理的,例如需要将应用程序分割成多个模块或按需加载某些功能模块。)

2.2 SplitChunksPlugin

SplitChunksPlugin 插件可以将公共的依赖模块提取到已有的入口 chunk 中,或者提取到一个新生成的 chunk。让我们使用这个插件去除之前示例中重复的 lodash 模块:
在webpack的配置文件中配置:

const path = require('path');module.exports = {mode: 'development',entry: {index: './src/index.js',another: './src/another-module.js',},output: {filename: '[name].bundle.js',path: path.resolve(__dirname, 'dist'),clean: true,},optimization: {splitChunks: {chunks: 'all',},},
};

使用 optimization.splitChunks 配置选项后构建,将会发现 index.bundle.js 和 another.bundle.js 已经移除了重复的依赖模块。从插件将 lodash 分离到单独的 chunk,并且将其从 main bundle 中移除,减轻了 bundle 大小。执行 npm run build 查看效果:
在这里插入图片描述

3.动态导入

终于到最后一个了-动态导入。
webpack 提供了两个类似的技术实现动态代码分离。第一种,也是推荐选择的方式,是使用符合 ECMAScript 提案 的 import() 语法 实现动态导入。第二种则是 webpack 的遗留功能,使用 webpack 特定的 require.ensure。让我们先尝试使用第一种。

3.1 使用符合 ECMAScript 提案 的 import() 语法

现在,我们不再静态导入 lodash,而是通过动态导入来分离出一个 chunk:
src/index.js:

//动态导入
function getComponent() {return import('lodash').then(({ default: _ }) => {const element = document.createElement('div');element.innerHTML = _.join(['Hello', 'webpack'], ' ');return element;}).catch((error) => 'An error occurred while loading the component');}getComponent().then((component) => {document.body.appendChild(component);
});

需要 default 的原因是自 webpack 4 之后,在导入 CommonJS 模块时,将不再解析为 module.exports 的值,而是创建一个人工命名空间对象来表示此 CommonJS 模块。参阅 webpack 4: import() and CommonJs 以了解更多有关信息。

打包:
在这里插入图片描述
lodash会分离到一个单独的 bundle。
由于 import() 会返回 promise,因此它可以和 async 函数 一起使用。下面是使用 async 简化后的代码:
src/index.js:

//动态导入 - async写法
async function getComponent() {const element = document.createElement('div');const { default: _ } = await import('lodash');element.innerHTML = _.join(['Hello', 'webpack'], ' ');return element;}getComponent().then((component) => {document.body.appendChild(component);});

vendors-node_modules_lodash_lodash_js.bundle.js 是一个由 Webpack 打包生成的 JavaScript 文件。它通常包含了 Lodash 库的代码,并可能还包含其他第三方库的代码,这取决于你的项目中使用了哪些库和配置。

Lodash 是一个流行的 JavaScript 实用工具库,提供了许多常用的功能和工具函数,用于简化 JavaScript 编程任务。lodash.js 是 Lodash 库的核心文件,其中包含了 Lodash 提供的各种功能和方法。

当你在项目中使用 Lodash 并通过 Webpack 打包时,Webpack 会将 Lodash 的代码打包成一个单独的文件,这就是 vendors-node_modules_lodash_lodash_js.bundle.js 的由来。打包成单独的文件有助于提高浏览器加载速度,并允许你在需要时进行缓存和异步加载。
我的理解就是把lodash单独分离出去了的,就是例子中的第二个文件,代码分离了,如果其他地方调用了的话也不用再打包一个bundle出来了。

3.2 使用 webpack 特定的 require.ensure

好像官网没举这个例子。有句话:

警告
require.ensure() 是 webpack 特有的,已被 import() 取代。

4.预获取/预加载模块

能看懂意思,不知道具体能用在代码里的哪里。。。

5.分析bundle

webpack打包出来的bundle,光从命令行感觉是很难看出些什么的,不大直观。刚好有插件能解决这个问题,以webpack-bundle-analyzer为例。
先安装:

npm install --save-dev webpack-bundle-analyzer

然后在webpack配置文件中配置:

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;module.exports = {// ...其他配置plugins: [new BundleAnalyzerPlugin()]
};

然后打包,完成了它会默认打开浏览器一个网页:
在这里插入图片描述

6.总结

1.webpack的代码分离方式:
入口起点:使用 entry 配置手动地分离代码。
防止重复:使用 入口依赖 或者 SplitChunksPlugin 去重和分离 chunk。
动态导入:通过模块的内联函数调用分离代码。
2.预获取/预加载模块,暂时不知道能干嘛
3.分析bundle,通过插件能够更直观的分析打包后的各个bundle包

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/221213.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AIGC - 环境搭建

一. 硬件环境 1. 超微7048主板,最多可搭载4块GPU 2. 2个Intel的 Xen至强 14核 CPU 3. 目前安装了一块Nvidia 的P40 GPU,后续根据需要还最多可以扩展3块GPU 4. 4T机械 2T Nvme固态, 5. 4条64G DDR4内存条,共 196G内存…

QT多项目管理

.pro文件配置解释:​​​​​​ Qt 中的多项目管理_qt子目录项目-CSDN博客Qt 模块化开发之 pro 子项目开发_qt 子项目-CSDN博客关于Qt编译库(1):在子项目中编译动态库并且使用_qt编译动态库后配置qt-CSDN博客QT release下的编译…

涵盖多种功能,龙讯旷腾Module第六期:输运性质

Module是什么 在PWmat的基础功能上,我们针对用户的使用需求开发了一些顶层模块(Module)。这些Module中的一部分是与已有的优秀工具的接口,一部分是以PWmat的计算结果为基础得到实际需要的物理量,一部分则是为特定的计…

排序算法(二)-冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序、基数排序

排序算法(二) 前面介绍了排序算法的时间复杂度和空间复杂数据结构与算法—排序算法(一)时间复杂度和空间复杂度介绍-CSDN博客,这次介绍各种排序算法——冒泡排序、选择排序、插入排序、希尔排序、快速排序、归并排序、基数排序。 文章目录 排…

排序-归并排序与计数排序

文章目录 一、归并排序1、概念2、过程3、代码实现4、复杂度5、稳定性 二、 计数排序1、思路2、代码实现3、复杂度:4、稳定性 一、归并排序 1、概念 是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已…

关键点检测☞png格式换bmp,且labelme标注的json中imagePath同步修改格式

import os import cv2 import jsondef bmp2jpg(in_img_path, out_dir_name): # .png -> .bmp# img = cv2.imread(in_img_path) # 彩色图片,位深24img =</

GDPU 数据结构 天码行空13

文章目录 一、【实验目的】二、【实验内容】三、实验源代码四、实验结果五、实验总结 一、【实验目的】 (1) 理解插入排序算法的实现过程&#xff1b; &#xff08;2&#xff09;理解不同排序算法的时间复杂度及适用环境&#xff1b; &#xff08;3&#xff09;了解算法性能…

Win11 跑通tensorRT

准备 1.安装cuda&#xff0c;成功之后文件夹如下图所示 2.下载cudnn&#xff0c;把cudnn对应的文件放在cuda里面 3.安装vs 4.安装对应cuda版本的tensorRT https://developer.nvidia.com/tensorrt-download 5.opencv安装 编译好 打开vs&#xff0c;配置环境 用vs打开tens…

PLC-Recorder V3版本软件升级方法

PLC-Recorder V3软件进行了架构优化&#xff0c;包括采集服务器、客户端、授权管理等组件。升级方法与V2版本相似&#xff0c;但是也有一些变化&#xff0c;说明如下&#xff1a; 一、从V2向V3版本升级 1、退出原PLCRecorder&#xff1a;关闭右下角的图标。 2、退出打开的离线…

模型部署系列:10x速度提升,Yolov8检测模型稀疏化——CPU上超500FPS

YOLOv8由广受欢迎的YOLOv3和YOLOv5模型的作者 Ultralytics 开发&#xff0c;凭借其无锚设计将目标检测提升到了一个新的水平。YOLOv8 专为实际部署而设计&#xff0c;重点关注速度、延迟和经济性。 [1] 详细内容请参阅 MarkAI Blog [2] 更多资料及工程项目请关注 MarkAI Githu…

2023年【A特种设备相关管理(锅炉压力容器压力管道)】考试题及A特种设备相关管理(锅炉压力容器压力管道)考试内容

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 A特种设备相关管理&#xff08;锅炉压力容器压力管道&#xff09;考试题是安全生产模拟考试一点通总题库中生成的一套A特种设备相关管理&#xff08;锅炉压力容器压力管道&#xff09;考试内容&#xff0c;安全生产模…

DockerCompose部署RabbitMQ集群

DockerCompose部署RabbitMQ集群 最近小黄在工作中正好需要部署RabbitMQ集群&#xff0c;借此来记录一下&#xff0c;也希望可以帮助到大家 前置条件 简单介绍一下咱们公司现有的条件以及想要达成的效果 服务器3台&#xff0c;3台都是属于一个专有网络中&#xff0c;也就是说3…

【开源】基于JAVA的桃花峪滑雪场租赁系统

项目编号&#xff1a; S 036 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S036&#xff0c;文末获取源码。} 项目编号&#xff1a;S036&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 游客服务2.2 雪场管理 三、数据库设…

关于“Python”的核心知识点整理大全19

目录 ​编辑 8.6.4 使用 as 给模块指定别名 8.6.5 导入模块中的所有函数 8.7 函数编写指南 8.8 小结 第9章 类 9.1 创建和使用类 9.1.1 创建 Dog 类 dog.py 1. 方法__init__() 2. 在Python 2.7中创建类 9.1.2 根据类创建实例 1. 访问属性 2. 调用方法 3. 创建多…

快速搭建知识付费平台?我有才,为你提供一站式解决方案

在当今数字化时代&#xff0c;知识付费已经成为一种趋势&#xff0c;越来越多的人愿意为有价值的知识付费。然而&#xff0c;公共知识付费平台虽然内容丰富&#xff0c;但难以满足个人或企业个性化的需求和品牌打造。同时&#xff0c;开发和维护一个属于自己的知识付费平台需要…

Oracle md5

SQL CREATE OR REPLACE FUNCTION MD5(passwd IN VARCHAR2) RETURN VARCHAR2 ISretval varchar2(32); BEGINretval : utl_raw.cast_to_raw(DBMS_OBFUSCATION_TOOLKIT.MD5(INPUT_STRING > passwd));RETURN retval; END; 测试 select md5(lw112190) from dual 效果

70套大数据可视化大屏模板,总有一款适合你(含演示示例)

分享70款还不错的前端数据可视化大屏源码 其中包含行业&#xff1a;智慧社区、智慧物业、政务系统、智慧交通、智慧工程、智慧医疗、智慧金融银行等&#xff0c;全网最新、最多&#xff0c;最全、最酷、最炫大数据可视化模板。 你可以点击预览获取查看该源码资源的最终展示效果…

三、JS逆向

一、JS逆向 解释&#xff1a;在我们爬虫的过程中经常会遇到参数被加密的情况&#xff0c;这样只有先在前端搞清楚加密参数是怎么生成的才能继续我们的爬虫&#xff0c;而且此时我们还需要用python去执行这个加密的过程。本文主要讲怎么在浏览器调试JS&#xff0c;以及Python执…

基于ssm企业人事管理系统的设计与实现论文

摘 要 进入信息时代以来&#xff0c;很多数据都需要配套软件协助处理&#xff0c;这样可以解决传统方式带来的管理困扰。比如耗时长&#xff0c;成本高&#xff0c;维护数据困难&#xff0c;数据易丢失等缺点。本次使用数据库工具MySQL和编程技术SSM开发的企业人事管理系统&am…

后端对数据库查询的时间格式化

方式一&#xff1a; 在属性上加入注解&#xff0c;对日期进行格式化&#xff0c;如&#xff1a; JsonFormat(pattern "yyyy-MM-dd HH:mm:ss") private LocalDateTime updateTime;方式二&#xff1a; 在WebMvcConfiguration 中扩展Spring MVC的消息转换器&#xf…