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自动化环境配置 (推荐靠谱…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
【项目实战】通过多模态+LangGraph实现PPT生成助手
PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
