微前端架構下-ModuleFederation篇

第4章 模塊聯邦實現微應用

4-1 基礎構建-React

基礎應用代碼安裝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
複製代碼

4-2 基礎配置 webpack.config.js

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"
  },
複製代碼

4-3 導出微應用

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'
            }
        })
    ],
複製代碼

4-4 導入應用模塊

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;
複製代碼

4-5 模塊聯邦實現 Vue3.0 微前端架構

完整代碼示例: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"
  }
}

複製代碼

4-5-1 在 home 應用中導出模塊

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",
      },
    }),

  ]
});

複製代碼

4-5-2 在layout應用中導入

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

相關文章
相關標籤/搜索