使用webpack5的模块联邦实现微前端思想

首先我们可以去了解一下webpack5的模块联邦技术的思想,在现在的开发中,微前端的思想和技术已经得到了相对广泛的应用.

webpack5的详细理念

我们模拟2个团队,团队app1开发组件部署到线上给团队app2使用,团队app2使用远程组件。

详细代码可以参照一下代码:

本地端(团队app1):

const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin');
const { ModuleFederationPlugin } = require("webpack").container;

module.exports = {
    devtool: false,
    entry: './src/main.js',
    mode: "development",
    devServer: {
      port: 3000,
      contentBase: path.join(__dirname, "dist"),
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            },
          {
            test: /\.vue$/,
            loader: 'vue-loader'
          }
        ]
    },
    plugins: [
        // 请确保引入这个插件!
        new VueLoaderPlugin(),
        new HTMLWebpackPlugin({
            template: path.resolve(__dirname, './public/index.html')
        }),
        // name	string	必传值,即输出的模块名,被远程引用时路径为${name}/${expose}
		// library	object	声明全局变量的方式,name为umd的name
		// filename	string	构建输出的文件名
		// remotes	object	远程引用的应用名及其别名的映射,使用时以key值作为name
		// exposes	object	被远程引用时可暴露的资源路径及其别名
		// shared	object	与其他应用之间可以共享的第三方依赖,使你的代码中不用重复加载同一份依赖
        new ModuleFederationPlugin({
            // 提供给其他服务加载的文件
            filename: "remoteEntry.js",
            // 唯一ID,用于标记当前服务
            name: "app1",
            library: { type: "var", name: "app1" },
            // 需要暴露的模块,使用时通过 `${name}/${expose}` 引入
            exposes: {
                './Header': "./src/components/Header.vue",
            }
          })
      ]
}

远程端(团队app2):

const path = require('path');
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const HTMLWebpackPlugin = require('html-webpack-plugin');
const { ModuleFederationPlugin } = require("webpack").container;

module.exports = {
    devtool: false,
    entry: './src/main.js',
    mode: "development",
    devServer: {
      port: 3001,
      contentBase: path.join(__dirname, "dist"),
    },
    module: {
        rules: [
            {
                test: /\.js$/,
                loader: 'babel-loader',
                exclude: /node_modules/
            },
          {
            test: /\.vue$/,
            loader: 'vue-loader'
          }
        ]
    },
    plugins: [
        // 请确保引入这个插件!
        new VueLoaderPlugin(),
        new HTMLWebpackPlugin({
            template: path.resolve(__dirname, './public/index.html')
        }),
        new ModuleFederationPlugin({
          name: "app2",
          remotes: {
          //文件app1的name filename
            app1: "app1@http://localhost:3000/remoteEntry.js",
          }
        })
      ]
}

这个时候有一个很重要的知识点就是在app2中使用app1中暴露出来的组件的时候,需要采用异步加载的方式,可以参考以下的实现方式:

<template>
  <div>
    <Header name="app2" />
  </div>
</template>

<script>
export default {
  components: {
    // Header: () => import("app1/Header"),
    Header(resolve) {
      require(["app1/Header"], resolve);
    }
  },
};
</script>

<style lang="scss" scoped></style>

项目到这里就可以完整的实现模块联邦技术了,从原理上来说,是可以采用webpack5+vue3+ts重新搭建一套基线项目的.

如果还是有问题,可以直接参考以下项目代码:

详细项目demo可以参考以下demo:

下载demo , 然后通过npm run start将两个项目都启动起来

webpack5模块联邦项目代码下载地址传送门

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

echo忘川

谢谢老板们

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值