webpack5
本文介绍 webpack5 和 webpack4 的区别
一、性能优化
1. 持久缓存
Webpack 5:内置文件系统缓存,大幅提升二次构建速度;Webpack 4:需使用 cache-loader 或第三方插件实现。
js
// webpack.config.js
module.exports = {
cache: {
type: 'filesystem', // 启用文件系统缓存
buildDependencies: {
config: [__filename] // 配置文件变化时重新缓存
}
}
};
2. 优化 Tree Shaking
Webpack 5:默认启用更严格的 Tree Shaking,移除未使用代码;Webpack 4:需手动配置。
- 更精确地识别和移除未使用代码(基于 ESM 静态分析)。
- 支持通过 sideEffects 标记无副作用的模块。
3, 并行处理
Webpack 5:内置支持多线程构建;Webpack 4:需使用第三方插件(如 happypack
)。
二、 内置了资源处理
使用 Asset Modules 替代 file-loader、url-loader 和 raw-loader,简化资源处理:
js
module.exports = {
module: {
rules: [
{
test: /\.png$/,
type: 'asset/resource', // 输出文件
},
{
test: /\.svg$/,
type: 'asset/inline', // 内联为 Base64
},
{
test: /\.txt$/,
type: 'asset/source', // 导出源代码
},
{
test: /\.jpg$/,
type: 'asset', // 自动选择导出文件或内联
parser: {
dataUrlCondition: {
maxSize: 4 * 1024 // 4KB 以下内联
}
}
}
]
}
};
三、模块联邦
Webpack 5 引入 Module Federation,支持微前端架构和动态加载远程模块:
1. 配置说明
js
// 远程应用配置
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'remoteApp',
filename: 'remoteEntry.js',
exposes: {
'./Button': './src/components/Button'
}
})
]
};
// 宿主应用配置
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'hostApp',
remotes: {
remoteApp: 'remoteApp@http://localhost:3001/remoteEntry.js'
}
})
]
};
// 使用
import Button from 'remoteApp/Button';
//...
2. 可能的坑
版本冲突:确保远程模块和宿主应用使用相同的依赖版本。
- 问题:远程和宿主应用使用同一依赖的不同版本,导致运行时错误(如 React Hooks 报错)。
- 解决:使用共享依赖配置,确保版本一致。
jsnew ModuleFederationPlugin({ shared: { react: { singleton: true, requiredVersion: '^17.0.2' }, 'react-dom': { singleton: true, requiredVersion: '^17.0.2' } } });
性能问题:远程模块体积过大或加载时机不当,影响首屏性能。
- 动态加载:确保远程模块在需要时才加载,避免影响初始加载时间。
jsx// 懒加载非关键模块 const RemoteComponent = React.lazy(() => import('remoteApp/Component')); // Suspense 提供加载状态 <React.Suspense fallback={<Spinner />}> <RemoteComponent /> </React.Suspense>
- 增加监控,确定远程模块加载时间和性能指标。
调试问题:远程模块调试可能不如本地模块方便。
- 解决:确保远程模块生成 Source Map,并在开发环境中使用
jsmodule.exports = { devtool: 'source-map', // 确保生成 Source Map // ... };
全局变量或样式冲突
样式冲突问题
- 问题:远程模块可能引入全局样式或变量,导致宿主应用样式错乱。
- 解决:避免编写全局样式,使用 CSS Modules 或 Scoped CSS,避免全局污染。
全局变量冲突
- 问题:远程模块可能修改全局变量(如 window 对象),导致宿主应用异常。
- 解决:约定使用命名空间,避免直接修改全局变量。
安全问题
- 问题:远程模块可能被篡改
- 解决办法:script 标签的 integrity 属性(Subresource Integrity, SRI)通过验证外部资源的完整性来防止中间人攻击和 CDN 被篡改的风险
管理问题
- 问题:怎么管理不同远程模块的版本和依赖?
- 解决办法:推荐特定场景使用。如低代码平台,共享不同的远程模块,不存在管理问题。
- 如果简单使用可以,则分享的模块需要上CDN版本化链接。