不小心将 Webpack 升级后我搞定了微前端。
嗨,我是你稳定更新、持续输出的勾勾。
今天项目升级的时候,把 Webpack 升级了一个版本。瞬间让我囧大了,你懂的,我就不说了。反正给我一顿操作啊,终于摆平了。
再梳理项目的时候,我用 Webpack 新版本的模块联邦还真实现了应用程序和应用程序之间的引用。一个微前端的雏形就出现了!
借这个机会,刚好把 Webpack 的微前端实现流程介绍一下。
创建两个应用
既然是应用和应用之间的引用,所以我们就创建两个项目,一个叫 app,一个叫 slide。
app 项目的配置文件 webpack.config.js 内容如下:
//app/webpack.config.js
const path = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
//微前端的模块
const ModuleFederationPlugin = require("webpack").container.ModuleFederationPlugin;
module.exports = {
mode:"development",
devtool:false,
entry:"./src/index.js",
output:{
filename:"build.js",
path: path.resolve(__dirname,"dist")
},
devServer:{
contentBase: path.join(__dirname, 'dist'),
port:8081
},
module:{
rules:[
{
test:/\.js$/,
exclude:/node_modules/,
use:{
loader:"babel-loader"
}
}
]
},
plugins:[
new HtmlWebpackPlugin({
title:"webpack5",
template:"./public/index.html"
}),
new ModuleFederationPlugin({
name:"remote",
// library:{type:"var",name:"remote"},
filename:"remoteEntry.js",
exposes:{ //导出
"./App":"./src/App.js"
}
})
]
}
Slide 项目的配置文件 webpack.config.js 内容如下:
const path = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
// 模块联邦
const ModuleFederationPlugin = require("webpack").container.ModuleFederationPlugin;
module.exports = {
mode:"development",
devtool:false,
entry:"./src/index.js",
output:{
filename:"build.js",
path: path.resolve(__dirname,"dist")
},
devServer:{
contentBase: path.join(__dirname, 'dist'),
port:3000
},
module:{
rules:[
{
test:/\.js$/,
exclude:/node_modules/,
use:{
loader:"babel-loader"
}
}
]
},
plugins:[
new HtmlWebpackPlugin({
title:"webpack5",
template:"./public/index.html"
}),
new ModuleFederationPlugin({
name:"slide",
library:{type:"var",name:"slide"},
remotes:{
"remote":"remote@http://127.0.0.1:8081/remoteEntry.js"
}
})
]
}
重点
在 ModuleFederationPlugin 实例化的时候传入参数 options 的字段说明。
name 模块名
library 目前看到的用法有 { type: "var" } { type: "commonjs-module" },可以用来指定模块的使用规范
remotes 需要依赖的模块名
exposes 暴露出的模块,可以有多个
shared app 打包暴露模块时,不会将 shared 打包,是两个应用的共享依赖,比如 react vue 等
注意:library 是对外导出的一种规范,前端使用 {type:"var"}。在引入的应用程序中这个字段不要加哈,不然会不显示内容,而被引入模块可以加上。
还有就是 exposes 和 remotes 的字段小伙伴们也要注意。
exposes 的暴露字段要写上 ./name
remotes 的字段跟暴露模块的 name 保持一致,里面别名的定义也要一致
最后,两个应用同时启动,就会发现最终你要的应用就把其他应用的模块也引入进来了(●'◡'●)。
喜欢的小伙伴可以 fork 去(ง •_•)ง。
https://github.com/cuiweijun/moduleFederation
推荐阅读:
前端人因为 Vue3 的 Ref-sugar 提案打起来了!
点点“赞”和“在看”,保护头发,减少bug。