日期: 2024 年 12 月 20 日

  • Monorepo+federation+defineAsyncComponent构建一栈式主分前端架构

    构建一栈式主分前端架构,结合 Monorepo、Federation 和 defineAsyncComponent 是一种现代且高效的开发模式,特别适用于大型项目或微前端架构。

    以下是如何将这些技术结合起来实现这一架构的详细步骤:

    1. Monorepo(单仓库多包管理)

    定义: Monorepo 是一种将多个相关的代码库存储在一个单一的版本控制系统中的方法。它允许你更方便地管理和协调多个项目的依赖关系和版本更新。

    工具选择:
    •Lerna:用于管理多个 npm 包。
    •Yarn Workspaces 或 npm workspaces:用于处理多个包之间的依赖关系。(我选的是pnpm,虽然我觉得pnpm这个词打起来最费劲,但我在.zshrc里面给它设置成了p)
    •Nx:不仅支持包管理,还提供了丰富的工具链来优化构建和测试流程。
    优点:
    •统一的代码风格和配置。
    •更容易进行跨项目依赖管理。
    •提高了团队协作效率,减少了重复工作。

    用Monorepo关键的地方有两个:

    1)配置package.json里面的”scripts”,根据调试和打包的组合配置参数。

    2)配置dependencies,将共用的部分放到项目根,不过这一点没有上面那条那么重要,属于优化。

    1. Federation(模块联邦)

    定义: 模块联邦允许多个独立的应用程序或微前端共享模块,而不需要通过传统的打包方式。实现步骤:
    •设置主机应用(Host App):
    •使用 Webpack 5 的 ModuleFederationPlugin 配置远程模块。
    •示例配置: new ModuleFederationPlugin({
    name: ‘hostApp’,
    filename: ‘remoteEntry.js’,
    remotes: {
    remoteApp: ‘remoteApp@http://localhost:3001/remoteEntry.js’,
    },
    shared: [‘react’, ‘react-dom’],
    });

    •设置远程应用(Remote App):
    •同样使用 ModuleFederationPlugin 暴露模块。
    •示例配置: new ModuleFederationPlugin({
    name: ‘remoteApp’,
    filename: ‘remoteEntry.js’,
    exposes: {
    ‘./Button’: ‘./src/Button’,
    },
    shared: [‘react’, ‘react-dom’],
    });

    优点:
    •独立部署和开发。
    •模块级别的共享,减少冗余代码。
    •动态加载远程模块,提升性能。

    当然,我用的是vue,上面是钉钉ai助理给的代码,没有仔细看。后面我会整理代码发布到github上供参考。

    1. defineAsyncComponent(异步组件)

    定义:defineAsyncComponent 是 Vue 3 提供的一个 API,用于定义异步组件。它可以按需加载组件,从而优化初始加载时间和性能。实现步骤:
    •在 Vue 项目中使用 defineAsyncComponent 加载远程组件。 import { defineAsyncComponent } from ‘vue’;

    const RemoteButton = defineAsyncComponent(() =>
    import(‘remoteApp/Button’)
    );

    export default {
    components: {
    RemoteButton,
    },
    };

    优点:
    •按需加载,减少初始加载时间。
    •提升用户体验,特别是在网络条件不佳的情况下。
    综合应用项目结构示例:monorepo/
    ├── packages/
    │ ├── host-app/
    │ │ ├── src/
    │ │ └── webpack.config.js
    │ ├── remote-app/
    │ │ ├── src/
    │ │ └── webpack.config.js
    │ └── shared-components/
    │ ├── src/
    │ └── webpack.config.js
    └── package.json
    构建与部署
    •构建:使用 Lerna 或 Nx 进行统一构建。
    •部署:可以分别部署主机应用和远程应用,确保每个应用可以独立更新和维护。
    总结通过结合 Monorepo、Federation 和 defineAsyncComponent,你可以创建一个高效、可扩展的一栈式主分前端架构。这种方式不仅提高了开发效率,还能有效管理和优化大型项目的复杂度。如果你有更多具体的技术问题或需要进一步的帮助,请随时告诉我!(部分内容由AI生成)

    实际上,我没有采用ssr的架构,而是采用普通的vite。

    实际的目录结构如下:

    /apps/one-main
      package.json
    /packages/one-basic
      package.json
    package.json
    pnpm-workspace.yaml

    one-main作为我的主应用,one-basic作为的分应用之一,后续还会有one-beau之类的,主应用是作为门户提供最终用户访问的门面的,分应用有两个作用,提供remote-component组件以及对remote-component的单独演示,同时也方便调试。

    总体上one-main和one-basic也是同构的,都是采用了https://starchart.cc/xiangshu233/vue3-vant4-mobile这个脚手架,我计划将其中的UI替换为naive-ui,我更喜欢这个简洁的风格。

    简单来说,Monorepo是为了这一组代码库方便联调,Federation提供应用间(远程)组件共享,defineAsyncComponent实现动态加载(远程)组件,将远程组件参数化。最终实现的是一个有限灵活度的模板可配置电子书系统。

    本方案的代码库:https://github.com/futuremeng/one-momorepo