【前沿技术】Webpack5

简介: 【前沿技术】Webpack5

1 引言

先说结论:Webpack5 模块联邦让 Webpack 达到了线上 Runtime 的效果,让代码直接在项目间利用 CDN 直接共享,不再需要本地安装 Npm 包、构建再发布了!

我们知道 Webpack 可以通过 DLL 或者 Externals 做代码共享时 Common Chunk,但不同应用和项目间这个任务就变得困难了,我们几乎无法在项目之间做到按需热插拔。

模块联邦是 Webpack5 新内置的一个重要功能,可以让跨应用间真正做到模块共享,所以这周让我们通过 webpack-5-module-federation-a-game-changer-in-javascript-architecture 这篇文章了解什么是 “模块联邦” 功能。

2 概述 & 精读

NPM 方式共享模块

想象一下正常的共享模块方式,对,就是 NPM。

如下图所示,正常的代码共享需要将依赖作为 Lib 安装到项目,进行 Webpack 打包构建再上线,如下图:

对于项目 Home 与 Search,需要共享一个模块时,最常见的办法就是将其抽成通用依赖并分别安装在各自项目中。

虽然 Monorepo 可以一定程度解决重复安装和修改困难的问题,但依然需要走本地编译。

UMD 方式共享模块

真正 Runtime 的方式可能是 UMD 方式共享代码模块,即将模块用 Webpack UMD 模式打包,并输出到其他项目中。这是非常普遍的模块共享方式:

对于项目 Home 与 Search,直接利用 UMD 包复用一个模块。但这种技术方案问题也很明显,就是包体积无法达到本地编译时的优化效果,且库之间容易冲突。

微前端方式共享模块

微前端:micro-frontends (MFE) 也是最近比较火的模块共享管理方式,微前端就是要解决多项目并存问题,多项目并存的最大问题就是模块共享,不能有冲突。

由于微前端还要考虑样式冲突、生命周期管理,所以本文只聚焦在资源加载方式上。微前端一般有两种打包方式:

  1. 子应用独立打包,模块更解耦,但无法抽取公共依赖等。
  2. 整体应用一起打包,很好解决上面的问题,但打包速度实在是太慢了,不具备水平扩展能力。

模块联邦方式

终于提到本文的主角了,作为 Webpack5 内置核心特性之一的 Federated Module:

从图中可以看到,这个方案是直接将一个应用的包应用于另一个应用,同时具备整体应用一起打包的公共依赖抽取能力。

让应用具备模块化输出能力,其实开辟了一种新的应用形态,即 “中心应用”,这个中心应用用于在线动态分发 Runtime 子模块,并不直接提供给用户使用:

对微前端而言,这张图就是一个完美的主应用,因为所有子应用都可以利用 Runtime 方式复用主应用的 Npm 包和模块,更好的集成到主应用中。

模块联邦的使用方式如下:

1. const HtmlWebpackPlugin = require("html-webpack-plugin");
2. const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
3. 
4. module.exports = {
5. // other webpack configs...
6. plugins: [
7. new ModuleFederationPlugin({
8. name: "app_one_remote",
9. remotes: {
10. app_two: "app_two_remote",
11. app_three: "app_three_remote"
12.       },
13. exposes: {
14. AppContainer: "./src/App"
15.       },
16. shared: ["react", "react-dom", "react-router-dom"]
17.     }),
18. new HtmlWebpackPlugin({
19. template: "./public/index.html",
20. chunks: ["main"]
21.     })
22.   ]
23. };

模块联邦本身是一个普通的 Webpack 插件 ,插件有几个重要参数:ModuleFederationPlugin

  1. name当前应用名称,需要全局唯一。
  2. remotes可以将其他项目的 映射到当前项目中。name
  3. exposes表示导出的模块,只有在此申明的模块才可以作为远程依赖被使用。
  4. shared是非常重要的参数,指定了这个参数,可以让远程加载的模块对应依赖改为使用本地项目的 React 或 ReactDOM。

比如设置了 ,在代码中就可以直接利用以下方式直接从对方应用调用模块:remotes: { app_two:  

1. "app_two_remote" }
2. 
3. import { Search } from "app_two/Search";
4. 
5. 这个 来自于 的配置:app_two/Searchapp_two
6. 
7. // app_two 的 webpack 配置
8. export default {
9.   plugins: [
10.     new ModuleFederationPlugin({
11.       name: "app_two",
12.       library: { type: "var", name: "app_two" },
13.       filename: "remoteEntry.js",
14.       exposes: {
15. Search: "./src/Search"
16.       },
17.       shared: ["react", "react-dom"]
18.     })
19.   ]
20. };

正是因为 在 被导出,我们因此可以使用 这个模块,这个模块对于被引用应用来说是一个本地模块。Searchexposes[name]/[exposes_name]

3 总结

模块联邦为更大型的前端应用提供了开箱解决方案,并已经作为 Webpack5 官方模块内置,可以说是继 Externals 后最终的运行时代码复用解决方案。

另外 Webpack5 还内置了大量编译时缓存功能,可以看到,无论是性能还是多项目组织,Webpack5 都在尝试给出自己的最佳思路,期待 Webpack5 正式发布,前端工程化会迈向一个新的阶段。

相关文章
|
27天前
|
缓存 前端开发 JavaScript
Webpack技术深度解析:模块打包与性能优化
【10月更文挑战第13天】Webpack技术深度解析:模块打包与性能优化
|
29天前
|
缓存 前端开发 JavaScript
深入探讨Webpack及其关键技术
【10月更文挑战第11天】深入探讨Webpack及其关键技术
|
29天前
|
前端开发 JavaScript 开发者
Webpack不同技术的探讨
【10月更文挑战第11天】Webpack不同技术的探讨
|
29天前
|
前端开发 JavaScript 开发者
Webpack不同技术的探讨
【10月更文挑战第11天】Webpack不同技术的探讨
|
6月前
|
缓存 JavaScript 前端开发
【TypeScript技术专栏】TypeScript与Webpack构建优化
【4月更文挑战第30天】本文探讨了优化TypeScript与Webpack构建性能的策略。理解Webpack的解析、构建和生成阶段是关键。优化包括:调整tsconfig.json(关闭不必要的类型检查,适配目标环境)和webpack.config.js(配置entry、output、resolve,使用压缩插件)。启用Webpack缓存和增量构建,利用代码拆分与懒加载,能有效提升构建速度和开发效率。
85 0
|
JavaScript 前端开发 Java
webpack打包技术
webpack打包技术
122 0
|
前端开发 JavaScript 开发者
前端技术-webpack 介绍 | 学习笔记
简介:快速学习前端技术-webpack 介绍
前端技术-webpack 介绍 | 学习笔记
|
JavaScript 前端开发 开发者
前端技术—webpack 打包 js 文件(2) | 学习笔记
简介:快速学习前端技术—webpack 打包 js 文件(2)
166 0
|
前端开发 JavaScript 开发者
前端技术—webpack 打包 css 文件 | 学习笔记
简介:快速学习前端技术— webpack 打包 css 文件
107 0
|
Web App开发 前端开发 JavaScript
前端技术周刊 2018-06-22:Webpack 生存指南
前端技术周刊 2018-06-22:Webpack 生存指南
126 0