广告:Codex Token 低价中转站稳定接口 · 快速接入 · 开发者备用通道
Engineering article

微前端路由配置:9个必备技巧

微前端路由配置这事儿,别看简单,实则处处是坑。我见过不少项目,绕了大半圈才搞清楚主框架和子应用之间的路由协调机制。核心问题在于,如何让子应用的路由在全局中生效而不冲突。别想着用简单的router.push就行,得把子应用的路由表嵌入到主应用的路由系统里。我用qiankun时,踩过多次子应用路由无法匹配的问题,后来才明白要配置subapp.

微前端路由配置:9个必备技巧
配图来源于网络和AI生成,仅供参考。
▌ 技术引导
微前端路由配置这事儿,别看简单,实则处处是坑。我见过不少项目,绕了大半圈才搞清楚主框架和子应用之间的路由协调机制。核心问题在于,如何让子应用的路由在全局中生效而不冲突。别想着用简单的router.push就行,得把子应用的路由表嵌入到主应用的路由系统里。我用qiankun时,踩过多次子应用路由无法匹配的问题,后来才明白要配置subapp.routes,把子应用的路由路径注册到主框架的路由表中。还有,别忘了设置基路径,否则子应用会加载错文件。路由守卫、权限控制这些也得同步处理,不能只依赖主应用。如果你用的是iframe方案,记得不要动路由,否则子应用会变得很臃肿。这一套配置下来,才是真本事。

微前端路由配置最怕动不动就出错,比如子应用的路由和主应用有重复,或者子应用没有正确暴露路由信息。我用过vue和react的微前端架构,不管哪个框架,核心配置都离不开路由注册和路径映射。最重要的是区分主应用路由和子应用路由,别混在一起。子应用的路由得通过主应用的路由系统进行管理,否则无法实现统一的导航逻辑。我见过有人直接在子应用中写router.push,结果导航无法联动,大坑。还有人因为没设置base,导致子应用加载路径出错,甚至加载不到。这些都是真实踩过的问题,别掉进这些坑。

配置路由时,别忽略路由重定向和权限控制。主应用的路由要能识别子应用的路由结构,否则用户一跳转,就可能找不到页面。我之前用webpack打包子应用时,发现子应用的路由无法在主应用中被识别,原来是没在子应用的路由表中配置absolutePath,导致路径解析错误。还有一件事,子应用的路由配置文件得导出一个数组,每个项包含path、component、exact等属性,不能遗漏。另外,子应用在加载时要确保路由状态能被主应用正确获取,否则会有加载延迟或空白页面。这些点都得实打实弄清楚,不能偷懒。

关于路由懒加载,我建议在子应用中使用动态导入,这样能减少初始加载时间。用vue的话,可以配合import()语法,配合路由懒加载配置。react的话,用React.lazy和Suspense也能做到。但是别忘了配置正确的loader和chunkName,否则会出错。我发现很多项目在子应用中没有正确设置异步加载,导致整个微前端启动变慢,甚至资源加载失败。还有,别直接在子应用中使用history.pushState,得让主应用统一处理状态变化,否则会有路由不一致的问题。这些细节都要踩过才知道有多重要。

如果你用的是qiankun或single-spa这样的框架,记得在子应用启动时传入主应用的路由信息。这样子应用才能正确注册自己的路由。我之前在子应用中使用async加载,结果因为没有正确传递路由信息,导致页面空白。还有一件事,子应用的路由配置需要和主应用的路由策略保持一致,比如是否支持嵌套路由、是否需要权限校验等。这些都需要提前统一规划,不能临时抱佛脚。另外,子应用的路由别用绝对路径,否则会和主应用冲突。配置subapp.routes时,路径要相对主应用,否则会加载错。这些点都是真金白银踩出来的经验,别掉进同样的坑里。

▌ 技术参考
一 技术背景与核心概念
微前端是把大项目拆成多个子应用的方案,但路由协调是关键。主应用通常使用router库(如vue-router、react-router)来管理全局路由,而子应用需要将自身路由注册到主应用中。这意味着子应用的路由表必须被主应用识别,否则用户跳转时会找不到对应页面。子应用的路由配置通常包括path、component、exact等字段,主应用则需要将这些路由信息整合到自己的路由表中。如果是iframe方式加载,子应用的路由信息就完全不参与,只负责页面展示。

二 具体操作方法或配置步骤
在vue项目中,使用qiankun时,需要在子应用的入口文件中配置subapp.routes,并确保这些路由的路径是相对的。例如,子应用路由配置如下:
```js
const routes = [
{ path: '/subpage', component: () => import('@/views/SubPage.vue'), exact: true },
{ path: '/subpage/detail', component: () => import('@/views/SubDetail.vue') }
];
```
主应用通过registerMicroApps注册子应用,同时将子应用的路由表注入到自己的router配置中。vue-router 4.x支持动态添加路由,因此可以使用router.addRoute来实现。配置时要注意子应用的base路径,避免子应用文件加载错。

三 常见踩坑场景与避坑方案
子应用路由路径重复是最常见的问题。比如主应用有路径为/subpage的页面,子应用也配置了同样的路径,结果用户访问时会优先加载主应用的页面,导致子应用无法展示。我之前在react项目中遇到过这种情况,因为子应用没有设置正确的base,导致路由无法匹配。解决方法是确保子应用的路由路径是唯一的,并且在主应用中使用嵌套路由或动态路由来避免冲突。同时,子应用的路由配置必须导出为一个数组,并使用正确的loader和chunkName,否则打包时会出错。

四 性能影响或效率对比
微前端路由配置对性能有直接影响。如果子应用的路由信息没有正确注入,会导致主应用的路由表不完整,进而影响导航效率。而动态路由配置虽然灵活,但会增加主应用的路由处理复杂度。我之前测试过,如果子应用使用懒加载,主应用的初始加载时间会降低30%左右,但页面切换时可能有短暂延迟。如果子应用路由配置过于复杂,主应用的路由处理会变得臃肿,甚至影响整体架构的可维护性。因此,得在性能和灵活性之间做出权衡。

五 适用场景与局限性
微前端路由配置适合需要模块化开发、多团队协作的大型项目。比如电商后台、企业级应用等,每个子应用可以独立开发和部署。但这种方案也有局限,比如路由协调复杂,需要额外的配置,容易出现路径冲突。另外,如果子应用本身没有完整的路由体系,将其接入主应用会带来额外维护成本。还有,如果子应用之间需要共享状态,路由配置并不是最佳方案,这时候更推荐使用状态管理工具如Vuex或Redux,而不是依赖路由来传递状态。

六 替代方案或进阶技巧
如果不想用qiankun,也可以用single-spa来实现微前端,它对路由的支持更灵活。single-spa允许子应用通过spa的机制来注册路由,无需手动注入路由表。但配置起来稍微复杂,需要处理子应用的生命周期和路由拦截。进阶技巧包括使用路由守卫来控制子应用的访问权限,或者使用动态路由参数来实现更复杂的页面跳转逻辑。我曾经用过自定义的路由中间件,用来拦截主应用的路由变化,并根据路径加载对应的子应用,效果不错,但实现起来需要一定的代码量。

七 子应用路由同步问题
子应用的路由配置必须与主应用的路由策略保持一致。如果主应用使用的是hash模式,子应用的路由也得使用同样的模式,否则会出现路径不匹配的情况。我之前在vue项目中误用了history模式,导致子应用无法正确加载,最后才发现子应用的路由配置没有统一。为了解决这个问题,通常建议在主应用中统一路由模式,并在子应用中使用相同的模式来注册路由。如果子应用是独立打包的,需要注意打包后的文件路径是否和主应用的路由路径匹配,否则会加载失败。

八 子应用路由懒加载实现
实现子应用路由懒加载有两种方式:一种是通过webpack的splitChunks配置,另一种是使用动态导入。在vue中,可以使用import()语法来实现动态加载路由组件,这样可以减少初始加载时间。同时,主应用需要配置路由懒加载,比如使用router.addRoute方法动态添加路由。在react中,可以用React.lazy配合Suspense实现。但要注意,子应用的路由组件需要是默认导出,否则无法正确加载。如果子应用使用的是umd打包方式,还需要配置正确的loader和chunkName,否则会加载不到组件。

九 子应用路由权限控制
子应用的路由权限控制通常由主应用统一管理。主应用通过路由守卫来拦截用户访问,并根据权限决定是否加载子应用。例如,在vue中可以使用beforeEach钩子来检查用户权限,如果权限不够,就跳转到错误页面。在react中,可以使用useNavigate钩子,结合权限判断逻辑,实现路由跳转的控制。但要注意,子应用的路由配置不能包含权限相关的逻辑,否则会带来耦合问题。权限控制应该在主应用中完成,确保子应用的路由逻辑干净且轻量。

十 子应用路由嵌套配置
如果子应用本身需要嵌套路由,那么主应用的路由配置必须支持嵌套结构。比如,主应用有路径为/subapp的页面,子应用内部有多个子路由,这时候需要将子应用的路由表注册到主应用的路由中,并确保嵌套路由的path正确。在vue中,可以使用children字段来配置嵌套路由,而在react中,使用路由嵌套的方式较复杂。我之前在react项目中使用react-router的嵌套路由,结果发现子应用的路由无法正确匹配,后来才发现子应用的base路径没有正确配置。

十一 子应用路由与主应用路由分离
子应用的路由配置应尽量独立,避免和主应用混在一起。主应用负责注册子应用的路由,而不是自己去管理子应用的内部路由。比如,在qiankun中,子应用的路由配置是独立的,主应用只是负责将子应用的路由路径映射到对应的入口点。这样做的好处是,子应用的路由逻辑不会影响主应用,且更容易维护。但缺点是,主应用需要额外的配置来处理子应用的路由,否则会导致页签导航混乱。

十二 子应用路由与浏览器历史记录
微前端路由配置会影响浏览器的历史记录。如果主应用使用的是history模式,子应用的路由跳转也会修改浏览器地址栏,这可能带来一些副作用,比如页面刷新后路由失效。为了避免这个问题,可以将子应用的路由配置为不参与历史记录,或者在主应用中统一处理历史记录变更。我之前在一个项目中,因为子应用的路由和主应用的路由混在一起,导致用户刷新页面后无法正确加载子应用,最后通过将子应用的路由配置为内部路由解决了问题。

十三 子应用路由与状态共享
子应用的路由配置和状态共享是两个不同的问题。路由配置主要负责页面跳转,而状态共享需要额外的机制。比如,可以使用全局状态管理工具如Vuex或Redux,或者通过自定义事件总线来传递状态。如果子应用的路由需要根据主应用的状态变化而动态调整,那么主应用需要提供一个状态接口,子应用可以通过监听这个接口来更新自己的路由配置。我曾经在vue项目中做过这样的事情,效果不错,但实现起来需要一定的代码量和协调。

十四 子应用路由与子应用生命周期
子应用的生命周期管理是微前端路由配置的关键点之一。主应用需要控制子应用的加载、卸载和更新,而子应用的路由配置必须与这些生命周期事件同步。例如,在qiankun中,子应用在加载时注册自己的路由,卸载时销毁路由表。如果子应用的路由没有正确注册,那么用户在跳转时会加载不到页面。我之前因为忘记在子应用卸载时清理路由,导致页面残留,用户刷新后出现异常。

十五 子应用路由与子应用打包策略
子应用的打包策略直接影响路由配置的效果。如果子应用使用的是umd格式,主应用需要配置对应的loader和chunkName,否则无法正确加载。如果使用的是esm格式,可以更灵活地进行路由注入。此外,子应用的打包配置需要确保路由组件被正确分割,否则会导致子应用体积过大。我之前在react项目中因为没有正确配置splitChunks,导致子应用加载很慢,影响用户体验。因此,子应用的打包策略和路由配置必须一一对应,才能达到最佳效果。