webpack5 模块联邦(Module Federation)
Webpack 5 增加了一个新的功能 “模块联邦”,它允许多个 webpack 构建一起工作。 从运行时的角度来看,多个构建的模块将表现得像一个巨大的连接模块图。 从开发者的角度来看,模块可以从指定的远程构建中导入,并以最小的限制来使用。
多个独立的构建可以组成一个应用程序,这些独立的构建之间不应该存在依赖关系,因此可以单独开发和部署它们。这通常被称作微前端,但并不仅限于此。
Webpack5 模块联邦让 Webpack 达到了线上 Runtime 的效果,让代码直接在项目间利用 CDN 直接共享,不再需要本地安装 Npm 包、构建再发布了! 我们知道 Webpack 可以通过 DLL 或者 Externals 做代码共享时 Common Chunk, 但不同应用和项目间这个任务就变得困难了,我们几乎无法在项目之间做到按需热插拔。
模块联邦可以将一个应用的包应用于另一个应用,同时具备整体应用一起打包的公共依赖抽取能力。
实践效果
App2 如下图所示:

将 App2 引入 App1 中:

Vite + React + TypeScript + Webpack5 实践
项目搭建
我们用 Vite 作为脚手架新建两个 React + Ts 项目,分别命名为 mainApp 与 otherApp:
npm init @vitejs/app
安装webpack的两个基本项:
npm i webpack webpack-cli --save-dev
安装webpack:
npm i -D webpack
安装webpack服务器 webpack-dev-server,让启动更方便:
npm i --save-dev webpack-dev-server
自动创建html文件 html-webpack-plugin:
npm i --save-dev html-webpack-plugin
清除无用文件 clean-webpack-plugin,将每次打包多余的文件删除:
npm i --save-dev clean-webpack-plugin
样式编译loader插件:
npm i --save-dev style-loader css-loader // css相关loader
npm i --save-dev node-sass sass-loader // scss 相关loader
npm i --save-dev file-loader url-loader // 加载其他文件,比如图片,字体
( 我的 node-sass 装不上,干脆不装了😕
安装babel:
npm i --save-dev @babel/core @babel/cli @babel/preset-env @babel/preset-react @babel/plugin-proposal-class-properties
npm i --save @babel/polyfill
npm i --save-dev babel-loader
安装TypeScript加载器:
npm install ts-loader --save-dev
项目配置
将两个项目的 package.json 文件中的 scripts 配置更改为:
"scripts": {
"start": "webpack-dev-server --open --mode production",
"dev": "webpack --mode development& webpack-dev-server --open --mode development",
"build": "webpack --mode production",
"preview": "vite preview"
},
在 src 目录下创建 bootstrap.tsx 文件,并将入口文件的内容放到里面,然后将 bootstrap 引入到入口文件中:
bootstrap.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import './index.css'
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>
)
index.ts
import('./bootstrap')
这时候会有以下报错:

关于这个问题,我们将 tsconfig.json 中 compilerOptions.isolatedModules 改为 false 即可。
然后记得将 index.html 中引入的入口文件改为 index.ts:

给两个项目分别在根目录下新建 webpack.config.js 配置文件,内容如下:
const path = require('path')
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const isDev = process.env.NODE_ENV === 'development'
module.exports = {
mode: 'development',
devtool: isDev ? false : 'eval-cheap-module-source-map',
entry: './src/index.ts', // 配置项目入口文件路径
output: {
filename: 'main.js', // 项目出口文件名称
path: path.resolve(__dirname, 'dist') // 将项目打包出口文件生成至根目录下的 dist 文件夹中
},
devServer: {
port: 4001, // APP1的端口设为4001, APP2的端口设为4002
hot: true
},
resolve: {
alias: {
"@": path.resolve(__dirname, 'src')
},
extensions: ['.ts', '.tsx',

最低0.47元/天 解锁文章
257

被折叠的 条评论
为什么被折叠?



