微前端架构下-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

相关文章
相关标签/搜索