微前端之 Webpack5 的 module federation

微前端之 Webpack5 的 module federation

代码在 https://github.com/GoldenaArcher/webpack5-study-case 的 module federation branch 下面,关于其他的配置,可以看 webpack5 查漏补缺系列。

目前的代码配置是这样的:

在这里插入图片描述

简单的说一下就是,目前有 3 个项目:

  • hello-world,也就是 home

    remote

  • lion

    remote

  • dashboard

    host

这里的 host 会使用 remote 开放的组件,也就是 home 和 lion 两个页面:

在这里插入图片描述

在这里插入图片描述

这里导出的是两个页面,但是是机上使用 webpack 也可以导出方法/库让 host 去使用。

remote 配置

remote 的配置如下:

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const { ModuleFederationPlugin } = require('webpack').container;

module.exports = {
  entry: { lion: './src/lion.js' },
  output: {
    filename: '[name].[contenthash:8].js',
    path: path.resolve(__dirname, 'dist/'),
    // default for webpack5: publicPath: 'auto'
    // default for webpack4: publicPath: ''
    publicPath: 'http://localhost:9002/',
    clean: true,
  },
  devServer: {
    port: 9002,
    static: {
      directory: path.resolve(__dirname, './dist'),
    },
    devMiddleware: {
      index: 'lion.html',
      writeToDisk: true, // by default is false
    },
  },
  // ...
  plugins: [
    new CleanWebpackPlugin(),
    new HtmlWebpackPlugin({
      filename: 'lion.html',
      template: 'src/page-template.hbs',
      title: 'Cute lion',
      description: 'Very cute lion cub',
      chunks: ['lion'],
    }),
    new ModuleFederationPlugin({
      name: 'LionApp',
      filename: 'remoteEntry.js',
      exposes: {
        './LionPage': './src/components/lion-page/lion-page.js',
      },
    }),
  ],
};

省略了一些不相关的配置,这里最重要的几个配置包括:

  • publicPath

    这里是 webpack 向外暴露的路由,如这个案例中暴露的是 http://localhost:9002/,那么只要使用了 module federation 的插件,那么别的项目就可以使用暴露的对应功能

    另外就是,绝对不能忘了最后一个 /,因为忘了这个我 debug 了好久为什么资源无法访问……

  • devServer

    开发用

  • ModuleFederationPlugin

    这里的配置决定了 remote 中有什么项目会被暴露出去,截至目前的版本,所有的选项都是可选的:

    在这里插入图片描述

    关于 shared、runtime 这种暂时还没碰到的就不说了,这里讲一下用到的属性:

    • name

      容器的名字

    • filename

      文件名,即其他人可以通过 XXXX/filename 访问的那个文件名,如:

      在这里插入图片描述

      在 9000 这个端口所访问的文件就是 9001/remoteEntry.js

    • exposes

      容器需要暴露的功能,接受 3 个参数类型,字符串,暴露的对象,以及暴露对象的数组,这里使用的就是数组类型。

remote 其实可以导出任何一个东西,如果想自己从 0 开始配置的话,也可以先试着从 remote 导出一个函数让别的 host 去使用。

host

host 配置

new ModuleFederationPlugin({
  name: 'App',
  remotes: {
    HelloWorldApp: 'HelloWorldApp@http://localhost:9001/remoteEntry.js',
    LionApp: 'LionApp@http://localhost:9002/remoteEntry.js',
  },
}),

这里没有放其他的配置是因为 dashboard 只是作为 consumer 去使用别的 remote 分享的功能。一个 host 同样也可以作为 remote 向别的项目分享功能。

这里 remotes 就是接受别的 remote 分享的功能,格式就是 {name}@{publicPath+filename}

host 使用 remotes

因为所有的 remotes 都是异步代码,因此可以使用 callback 或者 async/await,说句题外话,top level await 已经被在 ES2022 中 release 了,并且大部分浏览器支持了,感兴趣的可以试试看:

在这里插入图片描述

具体的代码为:

import('HelloWorldApp/HelloWorldPage').then((HelloWorldPageModule) => {
  // const HelloWorldPage = HelloWorldPageModule.default;
  const { HelloWorldPage } = HelloWorldPageModule;
  new HelloWorldPage().render();
});

如果 remote 是 export default ...,那么在 host 使用的时候需要使用注释中的代码。

具体来说,使用 webpack 配置 module federation 并不是很难,而且如果运用得当,使用 monorepo+module federation 的搭配去构建一个微前端的项目也能够解构一些比较复杂的项目。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值