在 Nuxt 3 中使用微前端(Micro Frontend, MFE)可以实现模块化、按需加载和跨应用路由跳转。相比 Nuxt 2,Nuxt 3 提供了原生 Composition API、Vite 支持以及更灵活的模块系统,使得微前端集成更方便。
1. 概念
- 主应用(Host) :负责加载和渲染子应用,管理全局路由与状态。
- 子应用(Remote) :独立部署的模块化 Nuxt 3 应用,可通过 Module Federation 暴露组件或页面。
- Module Federation:Webpack 5 的微前端实现方案,允许子应用暴露模块,主应用按需加载。
- 路由跳转:微前端下,需处理主应用和子应用之间的路由通信。
2. 原理
2.1 子应用导出模块
Nuxt 3 配合 Webpack Module Federation,通过 exposes
导出组件:
javascript
// remoteApp/nuxt.config.ts
import { defineNuxtConfig } from 'nuxt/config'
import { ModuleFederationPlugin } from 'webpack'
export default defineNuxtConfig({
build: {
extend(config) {
config.plugins?.push(
new ModuleFederationPlugin({
name: 'remoteApp',
filename: 'remoteEntry.js',
exposes: {
'./Widget': './components/Widget.vue'
},
shared: ['vue', 'vue-router']
})
)
}
}
})
name
:子应用名称。filename
:远程入口文件。exposes
:导出的组件列表。shared
:共享依赖,避免重复打包。
2.2 主应用导入模块
主应用通过 remotes
引入子应用组件:
javascript
// hostApp/nuxt.config.ts
import { defineNuxtConfig } from 'nuxt/config'
import { ModuleFederationPlugin } from 'webpack'
export default defineNuxtConfig({
build: {
extend(config) {
config.plugins?.push(
new ModuleFederationPlugin({
remotes: {
remoteApp: 'remoteApp@http://localhost:3001/remoteEntry.js'
},
shared: ['vue', 'vue-router']
})
)
}
}
})
主应用可以直接使用子应用暴露的组件:
xml
<script setup lang="ts">
import Widget from 'remoteApp/Widget'
</script>
<template>
<div>
<h1>Host App</h1>
<Widget />
</div>
</template>
2.3 路由跳转
Nuxt 3 使用 Composition API 的 useRouter
和 useRoute
进行路由操作。微前端中:
- 主应用内部跳转:
scss
const router = useRouter()
router.push('/dashboard')
- 子应用跳转到主应用或其他子应用:
typescript
// 子应用中
function navigateToHost(path: string) {
window.dispatchEvent(new CustomEvent('navigate', { detail: path }))
}
// 主应用中
window.addEventListener('navigate', (e: any) => {
const router = useRouter()
router.push(e.detail)
})
3. 对比
功能 | Nuxt 3 单体 | Nuxt 3 微前端 |
---|---|---|
模块拆分 | 不支持 | 支持按子应用拆分 |
部署 | 单包 | 子应用独立部署 |
路由 | 全局 | 需协调主子应用路由 |
组件复用 | 受限 | 可跨应用导入 |
4. 实践示例
4.1 创建子应用(Remote)
bash
npx nuxi init remoteApp
cd remoteApp
npm install
npm install -D webpack webpack-cli
- 配置
nuxt.config.ts
添加 Module Federation。 - 暴露组件
Widget.vue
。 - 启动服务:
npm run dev
,生成remoteEntry.js
。
4.2 创建主应用(Host)
bash
npx nuxi init hostApp
cd hostApp
npm install
npm install -D webpack webpack-cli
- 配置
nuxt.config.ts
添加remotes
。 - 在页面中引入
<Widget />
。 - 添加全局事件监听处理子应用路由跳转。
5. 拓展功能
- 状态共享 :通过 Pinia 或 Vue 3 的
provide/inject
实现主子应用状态共享。 - 权限控制:主应用统一管理路由权限,子应用仅渲染组件。
- 懒加载:使用动态 import 按需加载子应用,减少主应用首屏压力。
- 多子应用组合:支持多个微前端模块组合成复杂系统。
6. 潜在问题
- CSS 冲突:子应用样式可能污染主应用,建议使用 Scoped 或 CSS Module。
- 路由冲突:子应用路由与主应用冲突时,需要命名空间或前缀处理。
- 依赖版本冲突:Vue/Nuxt 版本需保持兼容。
- 性能开销:过多子应用增加网络请求和运行时开销。
7. 思路图示
lua
+-------------------+ +-------------------+
| Host App | | Remote App |
| | | |
| +---------------+ | | +---------------+ |
| | Nuxt Router |<-----> | | Widget.vue | |
| +---------------+ | | +---------------+ |
| | | |
| <Widget /> | | remoteEntry.js |
+-------------------+ +-------------------+