☰
Vue3 + TypeScript + Vite 微前端架构实战与排障指南
2026/10/13 20:17:13 网站建设 项目流程

做这套 “Vue 3 + TypeScript + Vite 微前端架构” 之前,我团队里其实已经有过一次微前端落地失败的教训。当时用的是老一套方案,硬接 Vue 2 工程,业务线之间样式互相污染、上线互相踩版本,维护成本高到一度想全部推翻重来。直到后端一个大中台项目提了三个子应用同时迭代的需求,我才下定决心把主框架换成 Vite + Vue 3 + TS,并重新选型微前端运行时。这个组合解决的核心问题很明确:让多个团队独立开发、独立部署,但又在一个页面里协同呈现,整体性能和开发体验还都要比旧方案好。

这篇文章我打算直接把从零搭建到生产排障的完整路径写出来,不绕概念,重点讲清楚方案选型背后的考量、Vite 和微前端兼容的坑、TS 类型共享怎么处理,以及我在真实项目里踩过的一系列问题。适合正在做技术选型的前端负责人,也适合被分到微前端改造任务、想少走弯路的开发同学。

1. 方案选型:这套组合到底解决了什么问题

1.1 为什么是 Vue 3 而不是继续留在 Vue 2

旧项目留在 Vue 2 的最大原因通常是存量代码多、插件生态成熟,很多人会觉得没必要为了新项目冒险升级。但如果你要在一个体系里同时跑多个子应用,Vue 2 的响应式系统和 TypeScript 结合其实是比较别扭的。Vue 2 的 Options API 在类型推导上需要大量装饰器或者额外的类型声明库,写起来不像原生 TS 那么顺手;而 Vue 3 的 Composition API 配合defineComponent和ref、computed这类 API,类型推导是天然的,开发体验完全不是一个量级。

另一个实际原因是新的微前端方案大多对现代框架适配更好。Vue 3 的组件实例模型更容易嵌入 Web Components 之类的容器,也更适合被其他框架的子应用加载。我当时的判断是:既然是新建一个大中台项目,从第一天就用 Vue 3,后续接新应用、招新人、做组件共享都会顺畅很多。

Vue 3 还有一个不容易察觉但很重要的优势:它的运行时体积和编译产物是现代 ES Module 化的,这对 Vite 的开发链路非常友好。Vite 在开发环境直接利用浏览器原生 ESM,不需要像 Webpack 那样把所有模块打包成 bundle,这个过程要求框架源码尽量少做 CommonJS 转换,而 Vue 3 从发布第一天就是纯 ESM 友好的,Vue 2 则一路带着各种 CJS 包袱,在这个场景下就明显吃亏。

1.2 Vite 带来的开发体验提升

Vite 是基于 esbuild 预构建依赖、用 Rollup 做生产打包的一套工具链。开发环境下依赖被预构建为 ESM 并缓存,源文件按需加载,冷启动速度可以做到毫秒级;改动一个 Vue 文件只更新对应模块,热更新响应非常快。这不是普通的感知提升,在微前端场景里,因为主应用和子应用往往有几十个页面、几百个组件,Webpack 冷启动动不动要一分钟以上,Vite 十几秒就能起来,热更新基本上是一瞬间。

生产构建方面 Vite 默认产出的是高度优化的 ESM 静态资源,配合现代浏览器可以做到按需加载,代码分割策略也相对可控。不过这里要提醒一句:Vite 的 rollup 配置和 Webpack 的 config 完全不是一个思路,很多在 Webpack 里做到的事(比如自定义 chunk 粒度、特定格式的 umd 输出)在 Vite 里都要绕一圈。如果你想直接拿 Vite 输出一个兼容微前端旧方案的 umd 包,会碰壁,这一点接下去会专门讲。

1.3 微前端的核心痛点:不是拆分,而是聚合

很多人第一次接触微前端,以为重点是“怎么把一个项目拆成几个应用”,其实真做完宏观架构之后你会发现,拆是简单的,难的是聚合。多个子应用要共享登录态、共享全局组件、统一路由状态,又要保持样式隔离和逻辑隔离,这个“聚合”才是架构设计的核心。

我选微前端架构,主要因为它能解决几个具体问题:

  • 不同团队的技术栈可以不同(虽然主栈统一,但某个子团队想用 React 写个对比实验页面,不应该被禁止);
  • 子应用可以独立开发、独立构建、独立发布,不需要每次都联动主应用发版;
  • 某个应用崩溃了不能把整个页面拖垮;
  • 公共依赖可以按策略抽离或共享,避免一个页面加载三份 Vue 运行时。

如果只是单仓库里多建几个文件夹,这些目标一个都实现不了。微前端本身不是银弹,但它能让你在“团队自治”和“产品统一”之间找到相对平衡点。

2. 架构设计:主应用与子应用的边界划分

2.1 主应用到底该管什么

架构的第一步是明确主应用和子应用的职责边界。我的实践结论是:主应用只做三件事——登录态与全局信息管理、路由分发、以及全局样式和公共 UI 的注入。业务功能一概下沉到子应用,主应用不写任何业务页面,只保留一个 layout 框架,比如顶栏、侧边栏、内容容器。

这个边界一旦模糊,就会出现“主应用带了三个页面的业务代码,子应用之间路由反复横跳”的局面,维护成本直接回到单体应用。主应用的代码要刻意保持精简,我甚至在代码审查规则里加了一条:主应用业务代码超过 xx 行必须拆出去。

路由分发方面,主应用只负责顶层路由的注册,比如/app1/开头的路径路由到子应用 A,/app2/开头的路径路由到子应用 B。子应用内部的路由完全由子应用自己管理,主应用不感知。这样子应用之间的路由互不干扰,也方便各自做独立的菜单和权限控制。

2.2 子应用的自治边界

子应用在架构上是完全独立的工程,有自己的 package.json、构建配置、路由表、状态管理。它在运行时被主应用加载,但代码层面不应该依赖主应用的任何内部实现。子应用对外只暴露两样东西:挂载函数(mount)和卸载函数(unmount),至于它内部是 Vue、React 还是别的框架,主应用完全不关心。

我见过很多团队做微前端,子应用里直接import { useUserStore } from '主应用路径',这种写法短时间内爽,但一旦主应用发版升级,子应用编译期就能挂掉。正确的做法是:跨应用的数据通信全部通过主应用提供的全局事件或全局 store 访问,不要直接引用代码。子应用内部的状态、请求、路由都在自己的边界里完成,只有这样,独立部署才真正成立。

2.3 仓库策略与版本管理

仓库策略我建议直接采用 monorepo。虽然微前端的子应用可以各自建 git 仓库,但在项目早期(特别是团队不大时),monorepo 可以让公共类型、公共工具、构建脚本的维护成本降到最低。我用 pnpm workspace 管理,根目录放一个packages/,下面分main/(主应用)、app-one/、app-two/等子应用,再放一个shared/抽公共类型和工具。

版本管理上,子应用之间不要强依赖彼此版本。主应用锁一个 Node 版本、一套构建镜像,子应用的版本变化不联动主应用。发布时各自打 tag、各自出 CI 产物,主应用只需在更新某个子应用配置时(比如注册信息变更)才发版。这个思路能避免微前端最让人头疼的“改一行代码测全链路”问题。

3. 运行时方案:Vite 与微前端框架的爱恨情仇

3.1 主流微前端方案对 Vite 的适配差异

这是整个技术选型里最值得展开的部分。微前端的主流方案有几类:一是 iframe 系列,二是 single-spa / qiankun 这类基于路由劫持的,三是基于 Web Components 的 micro-app,四是京东的 wujie 这类无侵入方案。想用 Vite,第一个需要确认的问题就是它们对 Vite 的支持程度。

先说 qiankun。qiankun 要求子应用导出bootstrap、mount、unmount生命周期,并且建议子应用构建为 umd 格式。Vite 默认产出的不是 umd,而是 ESM,虽然可以手动改成 umd,但 Vite 官方并不把 umd 作为推荐产物,SSR 之外场景强行用 umd 会遇到不少坑,比如代码拆分失效、动态导入帮你改名字、样式路径错乱等。所以如果你一开始就定下 Vite,qiankun 不是首选。

micro-app 走的是 Web Components 路线,加载子应用时创建自定义元素,把子应用的内容放在 shadow DOM 里。它的好处是子应用构建格式不强制 umd,Vite 产物也能兼容(前提是资源路径配好)。但 shadow DOM 带来的样式隔离是双刃剑,有些全局弹出层和第三方弹窗如果直接挂在 body 下,就可能脱离 shadow 边界导致样式丢失,需要额外的配置。

wujie 是我实际项目里最终采用的方案。它的设计思路更轻——无侵入式地加载子应用,不需要子应用更改构建格式来适配 umd,通过 iframe + Web Components 组合实现隔离,同时解决了 iframe 通信麻烦和 shadow DOM 样式边界的问题。对 Vite 子应用相对友好,这点在我实测下来比 qiankun 顺太多。

3.2 我为什么选 wujie

选 wujie 不是因为它功能最多,而是因为它在“能用 Vite + 保留原生开发体验”这件事上做得最省事。wujie 的加载模式可以简单理解为:用 iframe 加载子应用 HTML,但运行时把 iframe 里的 DOM 内容同步到主应用的容器里展示,同时保留 iframe 里的 JS 运行环境。这样样式隔离和 JS 隔离天然具备,又不存在 shadow DOM 的弹层问题。

还有一点我比较看重:wujie 支持子应用无感知接入,即使某个子应用因为历史原因暂时没有做任何微前端改造,也可以先通过 wujie 的“全量加载模式”跑起来,之后再做渐进优化。这种平滑过渡能力在大团队里非常关键,因为你不可能让所有子应用团队在同一时间完成改造。

实际命令上,主应用安装wujie-vue3,然后通过setupApp注册子应用信息,再在需要嵌入的地方用<WujieVue>组件渲染。不需要子应用改 webpack、不需要写额外的 webpack 插件,开发成本低了一大截。

3.3 Vite 构建配置里必须处理的几个点

不管采用哪种运行时方案,Vite 的构建配置在微前端场景下有几处是必须处理的。

第一是base。子应用如果部署在非根路径(比如https://domain.com/child-app/),base必须设为'/child-app/',否则打包出来的 JS 与 CSS 资源路径会全部指向根目录,加载直接 404。我见过不少团队上来先不配置,开发环境跑得好好的,一上生产全白屏,排查半天原来就是 base 忘配了。

第二是build.target。微前端往往要在主应用里处理来自不同时代的子应用,老的业务浏览器(低版本 Chrome、Safari 老版本)可能不支持部分 ESM 特性。建议统一设成es2018或按团队实际浏览器要求来定,不要追求过新导致兼容性翻车。

第三是build.rollupOptions.output。如果你的运行时方案确实要求某种特定格式(比如某些场景下需要 umd),这里就要手动指定格式和entryFileNames、chunkFileNames、assetFileNames,保证产物路径可控。不过 wujie 模式下通常不需要这一步,保持默认 ESM 就行。

第四是开发环境的跨域代理。子应用开发时通常跑在独立端口(比如 5174),主应用页面去请求子应用资源时会跨域,需要在主应用开发服务器里配置 proxy,把子应用的请求代理到对应端口。这个如果漏了,项目会加载不出内容,且报错信息比较隐晦。

4. TypeScript 在微前端中的正确姿势

4.1 公共类型怎么抽

TypeScript 在微前端里的价值不只是写了类型注解而已,更重要的是把跨应用共享的数据结构固化成类型。比如用户登录信息、订单状态枚举、接口返回体的约定,这些在单体项目里定义一次就行,但微前端拆了之后,如果每个子应用各自复制一份,很容易出现“主应用说 status 是 1,子应用判断成 '1'”这种低级又难查的 bug。

我的做法是在 monorepo 的shared/包里维护一份纯类型定义文件,子应用和主应用都通过 pnpm workspace 依赖它。这个包只包含.d.ts或者纯类型导出,不包含任何运行时代码,这样它不会在构建时造成额外体积,也不会带来循环依赖。

要注意的是:shared 包既然是编译期共享,就不要在这里放运行时逻辑,否则不同子应用构建出的实现可能不一致,反而造成真相分裂。我见过有团队把 API 请求函数也放进 shared,结果子应用各自打包了一遍 axios,接口封装稍有差异,最终线上表现不一致,排查成本很高。

4.2 运行时跨应用数据通信的类型定义

如果你使用 wujie 这类通过window全局对象来做跨应用通信的方案,TS 的类型声明要提前兜住。wujie 里父子应用可以通过window.$wujie来读取 props 和调用方法。这个window上多出来的全局字段,需要在某个公共类型声明文件里补齐,否则子应用里用window.$wujie会直接报 TS 错误。

我在 shared 包下建了一个global.d.ts:

interface WujieGlobalProps { user: UserInfo; token: string; navigate: (path: string) => void; } interface Window { $wujie: { props: WujieGlobalProps; bus: WujieBus; }; }

这样主应用注入的 props 在子应用里就有了完整的类型提示,公共事件的on/emit方法也一起定义了类型参数,避免把 eventBus 当 any 用。

4.3 子应用挂载函数与模块引入的 TS 配置

子应用如果没有用专门的生命周期插件,而是通过手动调用setupApp方式加载,子应用的入口文件需要显式导出mount和unmount函数。这种情况下 TS 配置里要保证入口文件被包含在编译范围内,并且导出的函数签名要和主应用期望的一致。

在 Vite + Vue 3 项目里,子应用入口一般是src/main.ts,里面创建 Vue 实例并挂载到主应用约定的 DOM 节点。TS 的index.d.ts如果提供了declare module '*.vue',Vue 单文件组件类型推导就能正常。我建议在所有子应用的tsconfig.json里统一开启"strict": true,并开启"moduleResolution": "bundler",否则 Vite 的别名 alias 在 TS 里会报找不到模块。

5. 实操手记:从零搭一套可运行的 Vite + Vue3 + wujie 微前端

5.1 主应用的搭建

我以主应用为例,说明这个落地过程。先用 Vite 官方脚手架创建 Vue 3 + TS 工程:

npm create vite@latest main-app -- --template vue-ts cd main-app npm install npm install wujie-vue3

然后需要在src/main.ts里引入并注册 wujie 插件:

import { createApp } from 'vue'; import WujieVue from 'wujie-vue3'; import App from './App.vue'; import router from './router'; const app = createApp(App); app.use(router); app.use(WujieVue); app.mount('#app');

接着在路由表里注册子应用的顶层路由。比如/order交给订单子应用,/user交给用户子应用:

// src/router/index.ts import { createRouter, createWebHistory } from 'vue-router'; const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), routes: [ { path: '/', redirect: '/order' }, { path: '/order', name: 'order', component: () => import('../views/OrderHost.vue'), }, { path: '/user', name: 'user', component: () => import('../views/UserHost.vue'), }, ], }); export default router;

OrderHost.vue里其实就是一个 wujie 的容器组件:

<template> <WujieVue name="order" url="http://localhost:5174/" :props="wujieProps" /> </template> <script lang="ts" setup> import { reactive } from 'vue'; const wujieProps = reactive({ user: { name: 'admin', roles: ['admin'] }, token: 'xxx', navigate: (path: string) => {}, }); </script>

这里name是子应用的唯一标识,url是子应用的地址。开发环境下可以是本地 dev server 地址,生产环境下可以是子应用部署后的静态地址。props是从主应用传给子应用的初始化数据,我们在这里传了用户信息和一些全局方法。

5.2 子应用的创建与接入

子应用工程结构上不需要特殊插件,直接用 Vite 创建即可。但有几个关键点:

第一个是入口文件上需要导出mount和unmount。以app-order为例:

// src/main.ts import { createApp, type App } from 'vue'; import { createRouter, createWebHistory } from 'vue-router'; import App from './App.vue'; import routes from './router'; let app: App<Element> | null = null; let router: ReturnType<typeof createRouter> | null = null; export async function mount(container: HTMLElement, props: Record<string, any>) { router = createRouter({ history: createWebHistory(), routes, }); app = createApp(App); app.provide('microProps', props); // 子应用里通过 inject 获取主应用透传数据 app.use(router); app.mount(container); } export async function unmount() { app?.unmount(); app = null; router = null; }

如果子应用同时也想独立开发(不依赖主应用直接打开),可以加一段环境判断:

// 仅独立运行时直接挂载 if (!window.$wujie) { const container = document.getElementById('app')!; mount(container, {}); }

第二个是子应用的build.outDir和base。我一般把子应用构建产物输出到dist,然后配合 nginx 配置到/order/路径下,base设成/order/,这样生产环境资源路径才能找对。

第三个是子应用内部的路由最好用createWebHashHistory而不是createWebHistory,尤其是子应用被嵌在“非根路径”下时,history 模式容易受主应用路由干扰。hash 模式虽然 URL 不好看,但在微前端场景里稳定第一,可以省掉很多路由丢失的问题。如果团队能接受,我建议子应用默认用 hash 路由。

5.3 主应用与子应用的联调

开发环境的联调,核心问题是跨域。我在主应用的vite.config.ts里加了代理:

import { defineConfig, loadEnv } from 'vite'; import vue from '@vitejs/plugin-vue'; export default defineConfig(({ mode }) => { return { plugins: [vue()], server: { port: 5173, proxy: { '/api': { target: 'http://localhost:8080', changeOrigin: true, }, '/order': { target: 'http://localhost:5174', changeOrigin: true, }, '/user': { target: 'http://localhost:5175', changeOrigin: true, }, }, }, }; });

因为主应用页面里通过url="http://localhost:5174/"直接加载子应用,如果子应用也跑了 5174 端口,浏览器访问主应用时加载这个地址并不存在跨域问题(iframe 加载不受同源限制)。但如果子应用里调接口要用/api路径,这时请求是发生在子应用域下的,就会遇到跨域。通过主应用代理把这些前缀转发到后端服务,可以统一规避。

还有一个小细节:子应用的 Vite 开发服务器需要开启cors: true,否则某些资源加载可能被浏览器拦截。虽然 iframe 场景一般不太触发,但 wujie 里 JS 是在 iframe 里运行的,有些子应用里的字体、图片、动态模块加载仍然可能遇到跨域,稳妥起见都打开。

5.4 生产部署配置要点

生产环境我采用的是“主应用反向代理承载子应用静态资源”的方式,部署结构大概是这样的:前后端共用一台 nginx,主应用跑在根路径,子应用产物分别放在/order/、/user/目录下,所有请求都先打到主应用的入口页,再由前端路由分发到对应的 wujie 容器加载子应用资源。

nginx 配置里要给子应用路径配置好try_files,否则子应用内部刷新页面时可能 404。举个例子:

location /order/ { alias /var/www/child/order/; try_files $uri $uri/ /order/index.html; }

如果子应用用的是 history 路由,这个配置尤其重要。如果用的是 hash 路由,其实不太容易触发,但我还是建议大家统一写好。

另一个生产环境的高频问题是子应用构建后的index.html里引用的 JS/CSS 路径。Vite 默认把资源放在assets/下,但如果路径不对,加载出来是 404。检查方法是直接curl一下子应用的index.html,看里面的<script>标签 src 是什么,再对照 nginx 目录结构确认。

6. 常见问题与排查技巧实录

6.1 开发环境子应用加载不出、白屏

这个我在第一次联调时遇到过。现象是主应用页面出来了,但子应用区域一直是空白。排查步骤我总结成了习惯:

  1. 先打开浏览器 DevTools Network,看子应用的 HTML 有没有被成功加载;
  2. 再确认子应用的 JS、CSS 有没有请求,有没有 404;
  3. 看控制台报错信息,尤其注意是否有跨域、CORS 错误;
  4. 确认子应用 dev server 是否正常启动,端口是否正确;
  5. 最后检查是否命中主应用路由,而不是因为路由没匹配到导致组件没渲染。

有一次我排查了很久,最后发现子应用的 dev server 端口改过,但主应用里url还是指到旧端口,这种低级错误在切换分支、切换环境时特别容易发生。

6.2 子应用切换菜单后白屏或找不到页面

这是典型的子应用路由配置问题。如果子应用已经加载成功过一次,但在子应用内部跳转另一个路由时白屏,优先检查子应用的 base 路径。子应用中/order/list和/order/detail这样的路由,浏览器刷新时会向服务器请求对应路径,nginx 如果没有配置try_files把请求落到index.html,就会出现 404 或白屏。

我的经验是,能上 hash 路由就上 hash 路由,尤其是多个团队并行开发、各自部署节奏不一致时,hash 路由能减少很多“环境相关”的诡异问题。如果你确实要 history 路由,一定要把 nginx 的try_files配到位,并且测试子应用内点击子路由刷新是否正常。

6.3 TypeScript 编译报 “Option 'baseUrl' is deprecated”

这是 TypeScript 5.x 之后引入的提醒。老项目里的tsconfig.json很喜欢配置"baseUrl": "./src"来配合短路径导入,但 TS 官方已经计划在 7.0 移除这个选项。实际处理很简单:

  • 不要再使用baseUrl,改用paths并配合"paths"里的相对路径写法;
  • 例如"@/*": ["src/*"],"paths"本身就支持相对于 tsconfig 所在目录的解析,不需要额外 baseUrl。

我统一把所有子应用和主应用的 tsconfig 都改成了新的写法,避免这个报错继续骚扰团队。

另外还有一条 Vite 的常见运行报错:

option 'node_options' 不是内部或外部命令或$ node_options=--max-old-space-size=4096 vite

这个一般是在 Windows 环境下手动执行类似命令导致的。node_options=xxx vite这种写法是 Linux shell 的语法,Windows 的 cmd/PowerShell 不认识。我的解决方法是:在 package.json 的 scripts 里写"build": "node --max-old-space-size=4096 node_modules/vite/bin/vite.js build",或者直接配置.npmrc里node-options="--max-old-space-size=4096",这样跨平台都能正常跑。

6.4 Vite 改了 Vue 文件不热更新

这个问题在 monorepo 场景下蛮常见的。如果你把共享组件放在packages/shared里,然后在子应用里引用它,Vite 默认只监听当前项目根目录下的文件,monorepo 里兄弟包的文件改动可能不会被触发热更新,只触发页面 reload,甚至什么都不触发。

我的解决方案是在 Vite 配置里显式把这个共享包纳入监听:

server: { watch: { ignored: ['!**/node_modules/@mycompany/shared/**'], }, fs: { allow: ['..'], }, }

简单说就是让 Vite 不要忽略对shared包的监听,同时因为shared在子应用工作区之外,fs.allow需要放开,否则开发服务器出于安全会拒绝访问工作区外的文件。我一开始没配,改 shared 包里的组件半天不刷新,还以为是 wujie 的问题,最后发现是 Vite 的文件监听没覆盖到。

6.5 http proxy error 与接口请求失败

开发环境下如果看到类似:

[vite] http proxy error: /api/form/list?...

这是主应用或子应用的 dev server 代理转发出了问题。最常见的原因是代理目标(比如http://localhost:8080)没有启动,或者后端接口路径根本不在那个端口。排查方法是先用 curl 直接请求目标地址,确认后端服务可用,再检查 vite.config 里的代理配置,注意pathRewrite不要写错路径前缀。

有时候代理目标启动慢,前端冷启动时就会报大量 proxy error,此时不用太紧张,等后端起来后刷新页面就好。但是如果接口一直失败,就要检查是不是代理路径匹配规则有问题,比如你代理了/api但实际请求是/api/v1,影响不大;如果是代理了/api但请求路径是/mock,那必然失败。

6.6 子应用样式污染与全局样式冲突

虽然 wujie 通过 iframe 做 JS 隔离,样式隔离也算相对完善,但如果你在主应用的index.html里引入了全局样式,而这个样式对某些 class 名有强约束,子应用内部的元素在某些特殊情况下仍然可能受到影响(比如使用:global或者部分第三方组件的样式挂载在 body 上)。

我团队里总结的规则是:主应用只保留布局级全局样式(比如 reset、字体、布局变量),不要写带业务类目名的复杂样式;子应用内部尽量用 scoped 样式;确实需要在子应用里覆盖第三方组件样式的,用独立的样式文件,不要写全局影响范围的样式。

6.7 热更新失效:改 JS 文件不刷新 JS

这其实是 Vite HMR 的一个老问题,在微前端模式里更容易踩。很多时候不是 Vite bug,而是子应用是通过 iframe 加载的,HMR 建立的是子应用 dev server 和浏览器之间的一条 WebSocket 连接,当子应用嵌在主应用页面中时,这条连接在嵌套 iframe 里的行为有时会异常,导致更新推不过来。

我的临时解决方法是关掉子应用的 HMR,改成改动文件后整页刷新,因为子应用一般不会频繁改动到需要秒级热更新。具体配置是server: { hmr: false }。如果团队同时改主应用和子应用,主应用保持 HMR 开启即可,子应用以刷新为主,开发效率不会下降太多。

7. 经验总结与个人体会

整套架构从选型到落地,前后大概花了三周时间。第一周在选型、搭基础骨架、搞清楚 Vite 和微前端运行的边界;第二周把两个核心子应用接进来,完成路由、登录态、公共数据的联调;第三周主要在生产环境和 CI 上打磨,解决了一些资源路径和部署细节。

我个人的几个核心感受是:第一,微前端不是一个框架能解决的,构建工具链、部署方案、团队协作约定缺一不可;第二,Vite + Vue 3 + TS 这个组合本身是很先进的,但和微前端结合时一定要先想清楚运行时方案,别拿 qiankun 硬配 Vite,绕远路;第三,monorepo 的共享类型比共享代码重要得多,把类型固化好,跨应用联调会顺畅非常多。

最后分享一个小技巧:生产环境排查问题时,我经常直接用浏览器的无痕窗口打开页面,然后看 Network 里资源请求顺序。微前端场景下资源加载链路比普通项目长,一旦有问题,最快定位的方法就是“顺着请求追”:主应用 HTML、主应用 JS、子应用 HTML、子应用 JS/CSS、子应用 API,看哪一步断了,问题就一目了然。多看几次,很多所谓的诡异问题其实都只是路径或代理配置问题。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询