【Webpack】webpack5 模块联邦(Module Federation)实践

webpack5 模块联邦(Module Federation)

Webpack 5 增加了一个新的功能 “模块联邦”,它允许多个 webpack 构建一起工作。 从运行时的角度来看,多个构建的模块将表现得像一个巨大的连接模块图。 从开发者的角度来看,模块可以从指定的远程构建中导入,并以最小的限制来使用。

多个独立的构建可以组成一个应用程序,这些独立的构建之间不应该存在依赖关系,因此可以单独开发和部署它们。这通常被称作微前端,但并不仅限于此。

Webpack5 模块联邦让 Webpack 达到了线上 Runtime 的效果,让代码直接在项目间利用 CDN 直接共享,不再需要本地安装 Npm 包、构建再发布了! 我们知道 Webpack 可以通过 DLL 或者 Externals 做代码共享时 Common Chunk, 但不同应用和项目间这个任务就变得困难了,我们几乎无法在项目之间做到按需热插拔。

模块联邦可以将一个应用的包应用于另一个应用,同时具备整体应用一起打包的公共依赖抽取能力。

实践效果

App2 如下图所示:
App2
将 App2 引入 App1 中:
App2

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', 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值