Webpack 5的新特性:Asset Modules与Dynamic Import
文章目录
- Asset Modules
- Asset Modules 类型
- 配置示例
- 分析
- Dynamic Import
- 动态导入语法
- 配置示例
- 分析
- 实际案例分析
- Asset Modules 实际案例
- Dynamic Import 实际案例
- 性能优化
- Asset Modules 性能优化
- Dynamic Import 性能优化
- 详细代码分析
- Asset Modules 代码分析
- Dynamic Import 代码分析
- 总结与讨论
- Asset Modules 总结
- Dynamic Import 总结
Webpack 5 引入了许多新特性,其中 Asset Modules 和 Dynamic Import 是两个非常重要的特性。这些特性极大地提高了 Webpack 的灵活性和性能。
Asset Modules
Asset Modules 是 Webpack 5 中引入的一种新的模块类型,用于处理各种类型的静态资源文件(如图片、字体、视频等)。Asset Modules 可以自动处理资源文件的加载和打包,使得开发过程更加简单。
Asset Modules 类型
Asset Modules 支持以下几种类型:
- Asset Module: 基础类型,用于处理静态资源文件。
- Asset Resource Module: 处理外部资源文件,不会被包含在最终的输出文件中。
- Asset Inline Module: 将小文件直接嵌入到输出文件中,而不是作为单独的文件。
- Asset URL Module: 生成一个 URL 指向资源文件。
配置示例
假设我们有一个项目结构如下:
src/- assets/- images/- logo.png- fonts/- Roboto-Regular.ttf
webpack.config.js
const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist')},module: {rules: [// 处理图片文件{test: /\.(png|jpe?g|gif)$/i,type: 'asset/resource',generator: {filename: 'images/[name][ext]'}},// 处理字体文件{test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,type: 'asset/resource',generator: {filename: 'fonts/[name][ext]'}}]}
};
index.js
import logo from './assets/images/logo.png';
import font from './assets/fonts/Roboto-Regular.ttf';console.log('Logo:', logo);
console.log('Font:', font);
分析
处理图片文件
- 使用 type:
'asset/resource'
将图片文件作为独立的资源文件处理。 - generator 选项指定输出路径和文件名。
处理字体文件
- 同样使用 type:
'asset/resource'
将字体文件作为独立的资源文件处理。 - 输出路径和文件名通过
generator
选项指定。
Dynamic Import
Dynamic Import 是一种按需加载模块的方法,可以在运行时动态地导入模块。这有助于减少初始加载时间并提高性能。
动态导入语法
import('./module.js').then((module) => {// 使用模块
});
配置示例
假设我们有一个项目结构如下:
src/- components/- About.js- Home.js- App.js
App.js
import React from 'react';class App extends React.Component {render() {return (<div><button onClick={() => this.loadAbout()}>Load About</button><button onClick={() => this.loadHome()}>Load Home</button></div>);}async loadAbout() {const About = await import('./components/About');console.log(About.default);}async loadHome() {const Home = await import('./components/Home');console.log(Home.default);}
}export default App;
webpack.config.js
const path = require('path');module.exports = {entry: './src/App.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist')},optimization: {runtimeChunk: 'single',splitChunks: {cacheGroups: {vendor: {test: /[\\/]node_modules[\\/]/,name: 'vendors',chunks: 'all'}}}}
};
分析
动态导入语法
- 使用 import() 函数动态导入模块。
- 返回一个 Promise 对象,可以在 .then() 中处理模块。
Webpack配置
- optimization.runtimeChunk 选项将运行时代码分离为单独的 chunk。
- splitChunks 选项用于分割代码块,提高代码复用率。
实际案例分析
Asset Modules 实际案例
假设我们要处理一个复杂的项目,包含多种类型的静态资源文件。
项目结构
src/- assets/- images/- logo.png- background.jpg- fonts/- Roboto-Regular.ttf- OpenSans-Regular.ttf- videos/- intro.mp4
webpack.config.js
const path = require('path');module.exports = {entry: './src/index.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist')},module: {rules: [// 处理图片文件{test: /\.(png|jpe?g|gif)$/i,type: 'asset/resource',generator: {filename: 'images/[name][ext]'}},// 处理字体文件{test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,type: 'asset/resource',generator: {filename: 'fonts/[name][ext]'}},// 处理视频文件{test: /\.(mp4|webm|ogg)$/,type: 'asset/resource',generator: {filename: 'videos/[name][ext]'}}]}
};
index.js
import logo from './assets/images/logo.png';
import background from './assets/images/background.jpg';
import font1 from './assets/fonts/Roboto-Regular.ttf';
import font2 from './assets/fonts/OpenSans-Regular.ttf';
import video from './assets/videos/intro.mp4';console.log('Logo:', logo);
console.log('Background:', background);
console.log('Font 1:', font1);
console.log('Font 2:', font2);
console.log('Video:', video);
Dynamic Import 实际案例
假设我们要实现一个动态加载页面的单页应用。
项目结构
src/- pages/- About.js- Home.js- Contact.js- App.js
App.js
import React from 'react';class App extends React.Component {state = {currentComponent: null};render() {const { currentComponent } = this.state;return (<div><button onClick={() => this.loadPage('About')}>Load About</button><button onClick={() => this.loadPage('Home')}>Load Home</button><button onClick={() => this.loadPage('Contact')}>Load Contact</button>{currentComponent && <currentComponent />}</div>);}async loadPage(pageName) {try {const module = await import(`./pages/${pageName}.js`);this.setState({ currentComponent: module.default });} catch (error) {console.error('Error loading page:', error);}}
}export default App;
webpack.config.js
const path = require('path');module.exports = {entry: './src/App.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist')},optimization: {runtimeChunk: 'single',splitChunks: {cacheGroups: {vendor: {test: /[\\/]node_modules[\\/]/,name: 'vendors',chunks: 'all'}}}}
};
性能优化
Asset Modules 性能优化
使用 asset/inline
模块类型
- 对于小文件,可以直接嵌入到输出文件中,减少 HTTP 请求次数。
- 使用
asset/url
模块类型
生成一个 URL 指向资源文件,适用于较大的文件。
webpack.config.js
module.exports = {module: {rules: [// 处理小图片文件{test: /\.(png|jpe?g|gif)$/i,type: 'asset/inline',generator: {filename: 'images/[name][ext]'},parser: {dataUrlCondition: {maxSize: 8 * 1024 // 8KB}}},// 处理大图片文件{test: /\.(png|jpe?g|gif)$/i,type: 'asset/url',generator: {filename: 'images/[name][ext]'}},// 处理字体文件{test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,type: 'asset/resource',generator: {filename: 'fonts/[name][ext]'}}]}
};
index.js
import logo from './assets/images/logo.png';
import background from './assets/images/background.jpg';
import font1 from './assets/fonts/Roboto-Regular.ttf';
import font2 from './assets/fonts/OpenSans-Regular.ttf';
import video from './assets/videos/intro.mp4';console.log('Logo:', logo);
console.log('Background:', background);
console.log('Font 1:', font1);
console.log('Font 2:', font2);
console.log('Video:', video);
Dynamic Import 性能优化
懒加载
使用 Dynamic Import 实现懒加载,只在需要时加载模块,减少初始加载时间。
预加载和预取
使用 和 提前加载关键资源。
webpack.config.js
module.exports = {entry: './src/App.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),publicPath: '/'},optimization: {runtimeChunk: 'single',splitChunks: {cacheGroups: {vendor: {test: /[\\/]node_modules[\\/]/,name: 'vendors',chunks: 'all'}}}}
};
App.js
import React from 'react';class App extends React.Component {state = {currentComponent: null};render() {const { currentComponent } = this.state;return (<div><button onClick={() => this.loadPage('About')}>Load About</button><button onClick={() => this.loadPage('Home')}>Load Home</button><button onClick={() => this.loadPage('Contact')}>Load Contact</button>{currentComponent && <currentComponent />}</div>);}async loadPage(pageName) {try {const module = await import(`./pages/${pageName}.js`);this.setState({ currentComponent: module.default });} catch (error) {console.error('Error loading page:', error);}}
}export default App;
详细代码分析
Asset Modules 代码分析
配置解析
- test: 匹配文件扩展名。
- type: 指定模块类型。
- generator: 指定输出路径和文件名。
- parser: 设置条件,例如最大大小。
实际应用
在 index.js 中导入资源文件,WebPack 自动处理加载和打包。
webpack.config.js
module.exports = {module: {rules: [// 处理小图片文件{test: /\.(png|jpe?g|gif)$/i,type: 'asset/inline',generator: {filename: 'images/[name][ext]'},parser: {dataUrlCondition: {maxSize: 8 * 1024 // 8KB}}},// 处理大图片文件{test: /\.(png|jpe?g|gif)$/i,type: 'asset/url',generator: {filename: 'images/[name][ext]'}},// 处理字体文件{test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,type: 'asset/resource',generator: {filename: 'fonts/[name][ext]'}}]}
};
index.js
import logo from './assets/images/logo.png'; // 内联数据
import background from './assets/images/background.jpg'; // URL
import font1 from './assets/fonts/Roboto-Regular.ttf'; // 资源文件
import font2 from './assets/fonts/OpenSans-Regular.ttf'; // 资源文件
import video from './assets/videos/intro.mp4'; // 资源文件console.log('Logo:', logo);
console.log('Background:', background);
console.log('Font 1:', font1);
console.log('Font 2:', font2);
console.log('Video:', video);
Dynamic Import 代码分析
配置解析
- runtimeChunk: 将运行时代码分离为单独的 chunk。
- splitChunks: 分割代码块,提高代码复用率。
实际应用
在 App.js 中使用 import() 函数动态加载模块。
webpack.config.js
module.exports = {entry: './src/App.js',output: {filename: 'bundle.js',path: path.resolve(__dirname, 'dist'),publicPath: '/'},optimization: {runtimeChunk: 'single',splitChunks: {cacheGroups: {vendor: {test: /[\\/]node_modules[\\/]/,name: 'vendors',chunks: 'all'}}}}
};
App.js
import React from 'react';class App extends React.Component {state = {currentComponent: null};render() {const { currentComponent } = this.state;return (<div><button onClick={() => this.loadPage('About')}>Load About</button><button onClick={() => this.loadPage('Home')}>Load Home</button><button onClick={() => this.loadPage('Contact')}>Load Contact</button>{currentComponent && <currentComponent />}</div>);}async loadPage(pageName) {try {const module = await import(`./pages/${pageName}.js`);this.setState({ currentComponent: module.default });} catch (error) {console.error('Error loading page:', error);}}
}export default App;
总结与讨论
Asset Modules 总结
优点
- 自动处理静态资源文件的加载和打包。
- 灵活的配置选项,可以根据文件大小选择不同的处理方式。
- 支持多种类型的静态资源文件。
缺点
- 需要合理配置,否则可能导致不必要的 HTTP 请求或过大的内联数据。
Dynamic Import 总结
优点
- 按需加载模块,减少初始加载时间。
- 提高应用性能,特别是在大型应用中。
- 支持懒加载和预加载。
缺点
- 需要合理配置,否则可能导致不必要的代码分割。
- 需要处理错误情况,例如模块加载失败。
相关文章:
Webpack 5的新特性:Asset Modules与Dynamic Import
文章目录 Asset ModulesAsset Modules 类型配置示例分析 Dynamic Import动态导入语法配置示例分析 实际案例分析Asset Modules 实际案例Dynamic Import 实际案例 性能优化Asset Modules 性能优化Dynamic Import 性能优化 详细代码分析Asset Modules 代码分析Dynamic Import 代码…...

解释python requests包的timeout
解释python requests包的timeout 哈哈哈。。。。垃圾python又来了 1 问题 你能看懂下面两个timeout的含义就不用看下面的内容了。 requests.get(http://example.com, timeout(2, 5)) requests.get(http://127.0.0.1:5000/api,timeout1)官网解释!!&am…...

蒙语学习快速方法,速记蒙语单词怎么学习更高效!
要高效学习蒙古语和速记单词,首先要掌握基础知识,如字母表和发音规则。接着,专注于学习日常用语和基础词汇,并运用记忆技巧如联想、发音和构词法来帮助记忆。利用专门的学习软件,如“蒙语学习通”,可以提供…...
Vue3组件通信13种方法
在 Vue3 中,组件之间的通信是构建应用程序的关键 1. 父组件向子组件传递数据 (Props)「父组件:」「子组件:」 2. 子组件向父组件传递数据 (Emit)「父组件:」「子组件:」 3. 兄弟组件通信 (Mitt)「发送事件的组件:」「接收事件的组件:」 4. 透传 Attributes ($attrs)「父组件:」…...

Servlet入门:服务端小程序的初试(自己学习整理的资料)
目录 一.前言 二.建立基础结构编辑 三.具体步骤 找到Tomcat文件并打开Tomcat。 在webapps中创建一个自己的文件夹。 在classes中新建一个Java文件。 在lib中导入需要的jar文件包。 配置环境变量 在Java文件的目录下打开cmd并输入 javac -d . HelloServlet.java进行…...
代码随想录算法训练营第三七天| 动态规划:完全背包理论基础 518.零钱兑换II 377. 组合总和 Ⅳ 322. 零钱兑换
今日任务 动态规划:完全背包理论基础 518.零钱兑换II 377. 组合总和 Ⅳ 322. 零钱兑换 518.零钱兑换II 题目链接: . - 力扣(LeetCode) class Solution {public int change(int amount, int[] coins) {int[] dp new int[amount …...
[报错解决] 运行MATCHA时需要在线下载Arial.TTF字体,但是无法连接huggingface
一、报错详情 requests.exceptions.ConnectTimeout:(MaxRetryError("HTTPSConnectionPool(hosthuggingface.co, port443): Max retries exceeded with url: /ybelkada/fonts/resolve/main/Arial.TTF (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnec…...

B-树(不是B减树)原理剖析(1)
目录 B树的主要特性: B树的操作: B树的优点: 为什么要发明出B-树? B树的概念和原理剖析 原理图讲解(部分讲解在图中) 初始化结点: 处理数据数量计算(了解) 底层代码实现(加深理解) 前些日子我们学了AVl树&…...

【shell脚本8】Shell脚本学习--其他
目录 编辑 Shell输入输出重定向 重定向深入讲解 Here Document Shell输入输出重定向 Unix 命令默认从标准输入设备(stdin)获取输入,将结果输出到标准输出设备(stdout)显示。一般情况下,标准输入设备就是键盘,标准输出设备就是终端&…...

《深度学习》ResNet残差网络、BN批处理层 结构、原理详解
目录 一、关于ResNet 1、什么是ResNet 2、传统卷积神经网络存在的问题 1)梯度消失和梯度爆炸问题 2)训练困难 3)特征表示能力受限 4)模型复杂度和计算负担 3、如何解决 1)解决梯度问题 BN层重要步骤: 2…...
javadoc:jdk 9通过javadoc API读取java源码中的注释信息(comment)
几年前写过一博客:《java:通过javadoc API读取java源码中的注释信息(comment)》,简单介绍了通过javadoc API读取源码注释的流程。 那时还是用JDK 1.8。但是在JDK9环境下JDK 1.8的那一套API就不能用了。JDK 9提供了一套新的javadoc API实现注释代码的读取…...
nordic使用FDS保存数据需要注意的地方
FDS使用常见问题 大家在使用FDS模块时,经常碰到的问题有如下几种: FDS不支持掉电保护,所以在Flash操作过程中出现了掉电,FDS行为将未知OTA的时候,新固件的FDS page数目一定要等于老固件的FDS page数,否则将出现不可知行为fds_record_write或者fds_record_update后,强烈…...
docker-compose集群(单机多节点)环境搭建与使用
此方案已经经过生产环境验证,可放心大胆使用如果喜欢,欢迎点赞👍收藏❤️评论噢~ 略去 Docker 和 Docker Compose 安装部分,如果有需要的同学,可以评论,创建 docker-compose.yml 文件并配置 Nacos 集群和 M…...
从静态多态、动态多态到虚函数表、虚函数指针
多态(Polymorphism)是面向对象编程中的一个重要概念,它允许不同类的对象对同一消息做出不同的响应。多态性使得可以使用统一的接口来操作不同类的对象,从而提高了代码的灵活性和可扩展性。 一、多态的表现形式 1. 静态多态&…...

用 Pygame 实现一个乒乓球游戏
用 Pygame 实现一个乒乓球游戏 伸手需要一瞬间,牵手却要很多年,无论你遇见谁,他都是你生命该出现的人,绝非偶然。若无相欠,怎会相见。 引言 在这篇文章中,我将带领大家使用 Pygame 库开发一个简单的乒乓球…...

基于大数据可视化的化妆品推荐及数据分析系统
作者:计算机学姐 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等,“文末源码”。 专栏推荐:前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏:Java精选实战项目…...

Java项目实战II基于Java+Spring Boot+MySQL的汽车销售网站(文档+源码+数据库)
目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导。获取源码联系方式请查看文末 一、前言 在数字化时…...
数学基础 -- 微积分最优化之一个最简单的例子
微积分中的一个最简单的最优化例子 问题描述 假设你有一条长度为 10 米的栅栏,你需要围成一个矩形的鸡舍,使得围成的面积最大。求这个矩形的长和宽应是多少,以使得面积最大。 步骤 设定变量: 设矩形的长为 x x x 米࿰…...

kubernetes K8S 结合 Istio 实现流量治理
目录 1.Istio介绍? 1.1 Istio是什么? 1.2 Istio流量管理 1.2.1 熔断 1.2.2 超时 1.2.3 重试 2.Istio架构 3.istio组件详解 3.1 Pilot 3.2 Envoy 3.3 Citadel 3.4 Galley 3.5 Ingressgateway 3.5 egressgateway 扩展、k8s1.23及1.23以下版…...

Selenium with Python学习笔记整理(网课+网站持续更新)
本篇是根据学习网站和网课结合自己做的学习笔记,后续会一边学习一边补齐和整理笔记 非常推荐白月黑羽的学习网站: 白月黑羽 (byhy.net) https://selenium-python.readthedocs.io/getting-started.html#simple-usage WEB UI自动化环境配置 (推荐靠谱…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...

C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)
Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败,具体原因是客户端发送了密码认证请求,但Redis服务器未设置密码 1.为Redis设置密码(匹配客户端配置) 步骤: 1).修…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...

排序算法总结(C++)
目录 一、稳定性二、排序算法选择、冒泡、插入排序归并排序随机快速排序堆排序基数排序计数排序 三、总结 一、稳定性 排序算法的稳定性是指:同样大小的样本 **(同样大小的数据)**在排序之后不会改变原始的相对次序。 稳定性对基础类型对象…...

Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...