基礎應用代碼安裝css
// webpack5
npm install webpack webpack-cli html-webpack-plugin css-loader style-loader babel-loader @babel/core @babel/preset-env @babel/preset-react webpack-dev-server -D
npm install react react-dom
複製代碼
基礎代碼:html
// ======insex.html========
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>RootReact</title>
</head>
<body>
<!-- 加一行註釋 -->
<div id="root"></div>
</body>
</html>
複製代碼
// ======insex.js========
import React from "react"
import ReactDom from "react-dom"
import App from "./App"
ReactDom.render(<App/>,document.getElementById('root'))
// ======App.js===========
import React from "react"
import User from "./User"
let App = () => {
return (
<div> <h3>webpack55</h3> <User/> </div>
)
}
export default App;
// ===== User.js==========
import React from "react"
const User = ()=>{
return (
<div> UserList </div>
)
}
export default User
複製代碼
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// entry 入口,output出口,module模塊,plugins 插件 mode工做模式,devServer開發服務器
// mode 工做模式
mode: 'development', // production 、 development、none
// 入口
entry: './src/index.js',
// 出口
output: {
filename: './bundle.js',
path: path.resolve(__dirname, 'dist')
},
// 模塊
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader',
options: {
presets: [
'@babel/preset-env',
'@babel/preset-react'
]
}
}
]
},
]
},
// 插件
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
// 服務器
devServer: {
contentBase: path.join(__dirname, 'dist'),
port: 3000,
open: true
},
}
複製代碼
package.json 啓動命令:前端
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build":"webpack",
"start":"webpack serve"
},
複製代碼
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 導入模塊聯邦插件
const Mfp = require('webpack').container.ModuleFederationPlugin;
^^^^^^^^Codes^^^^^^^^^^^^^
// 插件
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
// 實例化模塊聯邦插件
new Mfp({
// 對外提供的打包後的文件名,引入時使用
filename:'myuser.js',
// 微應用(模塊) 名稱,相似 single-spa的團隊名字
name:'study',
exposes:{
// 具體的一個文件能夠看成一個模塊應用,
// 每個應用都有一個名字和具體指定的代碼文件
// 名字:具體打包的代碼文件
'./xx':'./src/User.js',
'./goods':'./src/Goods.js'
}
})
],
複製代碼
const Mfp = require('webpack').container.ModuleFederationPlugin
// 插件
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new Mfp({
// // 微應用(模塊) 名稱,當前模塊本身的名字
name:'roots',
// 導入模塊
remotes:{
// 導入後給模塊起個別名:"微應用名稱@地址/導出的文件名"
one:"study@http://localhost:3001/myuser.js"
}
})
],
複製代碼
在組件中使用vue
// const xx = React.lazy(()=>import("導入時模塊別名/導出時具體文件對應的名字"))
const Us = React.lazy(()=>import("one/xx"))
const Gos = React.lazy(()=>import("one/goods"))
let App = () => {
return (
<div> <h3>webpack5 root</h3> <User/> <React.Suspense fallback="Loading app"> <Us /> <Gos /> </React.Suspense> </div>
)
}
export default App;
複製代碼
完整代碼示例:modulefederationvue3: 基於模塊聯邦實現的 Vue3.0 微前端架構示例 (gitee.com)node
package.jsonreact
{
"name": "@vue3-demo/layout",
"private": true,
"version": "1.0.0",
"scripts": {
"start": "webpack serve",
"serve": "serve dist -p 3001",
"build": "webpack --mode production",
"clean": "rm -rf dist"
},
"dependencies": {
"@babel/core": "^7.13.16",
"babel-loader": "^8.2.2",
"serve": "^11.3.2",
"vue": "^3.0.0-rc.5",
"vue-router": "^4.0.0",
"vuex": "^4.0.0"
},
"devDependencies": {
"@vue/compiler-sfc": "3.0.0",
"css-loader": "5.2.4",
"file-loader": "6.2.0",
"html-webpack-plugin": "5.3.1",
"mini-css-extract-plugin": "0.9.0",
"url-loader": "4.1.1",
"vue-loader": "16.0.0-beta.8",
"webpack": "5.35.0",
"webpack-dev-server": "3.11.2",
"webpack-cli": "4.6.0",
"sass": "^1.26.5",
"sass-loader": "^8.0.2"
}
}
複製代碼
home\webpack.config.jswebpack
const { ModuleFederationPlugin } = require("webpack").container;
module.exports = (env = {}) => ({
^^^^^^^………………^^^^^^^^^^^
plugins: [
new VueLoaderPlugin(),
// 模塊聯邦
new ModuleFederationPlugin({
name: "home",
filename: "remoteEntry.js",
// 導出
exposes: {
"./User": "./src/components/User",
// "./Button": "./src/components/Button",
},
}),
]
});
複製代碼
layout\webpack.config.jsgit
const { ModuleFederationPlugin } = require("webpack").container;
…………
module.exports = (env = {}) => ({
plugins: [
…………
new ModuleFederationPlugin({
name: "layout",
filename: "remoteEntry.js",
// 導入
remotes: {
importUser: "home@http://localhost:3002/remoteEntry.js",
},
exposes: {},
}),
]
});
複製代碼
layout\src\views\About.vueweb
<template>
<div class="about">
永遠記得 西嶺老溼 愛你
<hr>
<p>開啓home應用的3002端口應用可見,模塊聯邦內容</p>
<User />
</div>
</template>
<script>
import { defineAsyncComponent } from "vue";
// 導入模塊聯邦組件
const User = defineAsyncComponent(() => import("importUser/User"));
export default {
components: {
User
}
};
</script>
複製代碼
寫好基礎代碼及對應配置後,分別啓動 home 及 layout 兩個應用項目就能夠在 layout 應用的 about 中看到 home 應用中的 User 組件的內容了;vue-router