前端微前端架构:别再把所有功能都放在一个应用里了
前端微前端架构别再把所有功能都放在一个应用里了各位前端同行咱们今天聊聊前端微前端架构。别告诉我你还在把所有功能都放在一个应用里那感觉就像在一个房间里放了所有家具。为什么你需要微前端架构最近看到一个项目单页应用体积达到 10MB构建时间达到 10 分钟我差点当场去世。我就想问你是在开发应用还是在开发操作系统微前端的优势模块化将大型应用拆分为小型、独立的微应用每个微应用负责特定的功能。独立开发不同团队可以独立开发和部署微应用提高开发效率。独立部署每个微应用可以独立部署减少了部署风险。技术栈灵活不同微应用可以使用不同的技术栈适应不同团队的技术偏好。可扩展性可以轻松添加新的微应用而不影响现有功能。性能优化只加载当前需要的微应用减少了初始加载时间。反面教材// 反面教材单体应用 import React from react; import ReactDOM from react-dom; import Home from ./pages/Home; import About from ./pages/About; import Contact from ./pages/Contact; import Dashboard from ./pages/Dashboard; import Admin from ./pages/Admin; import Settings from ./pages/Settings; // 此处省略100个页面 function App() { return ( div Routes Route path/ element{Home /} / Route path/about element{About /} / Route path/contact element{Contact /} / Route path/dashboard element{Dashboard /} / Route path/admin element{Admin /} / Route path/settings element{Settings /} / // 此处省略100个路由 /Routes /div ); } ReactDOM.render(App /, document.getElementById(root));毒舌点评这代码我看了都替你的项目着急。单体应用这么大你是想让你的构建过程变成马拉松吗前端微前端架构的正确姿势1. 使用 Module Federation// 正确姿势使用 Module Federation // 主机应用 webpack.config.js const { ModuleFederationPlugin } require(webpack).container; module.exports { plugins: [ new ModuleFederationPlugin({ name: host, remotes: { home: homehttp://localhost:3001/remoteEntry.js, about: abouthttp://localhost:3002/remoteEntry.js, dashboard: dashboardhttp://localhost:3003/remoteEntry.js, }, shared: { react: { singleton: true, requiredVersion: ^18.0.0, }, react-dom: { singleton: true, requiredVersion: ^18.0.0, }, react-router-dom: { singleton: true, requiredVersion: ^6.0.0, }, }, }), ], }; // 微应用 webpack.config.js const { ModuleFederationPlugin } require(webpack).container; module.exports { plugins: [ new ModuleFederationPlugin({ name: home, filename: remoteEntry.js, exposes: { ./App: ./src/App, }, shared: { react: { singleton: true, requiredVersion: ^18.0.0, }, react-dom: { singleton: true, requiredVersion: ^18.0.0, }, }, }), ], }; // 主机应用中使用微应用 import React, { lazy, Suspense } from react; const HomeApp lazy(() import(home/App)); const AboutApp lazy(() import(about/App)); const DashboardApp lazy(() import(dashboard/App)); function App() { return ( div Suspense fallback{divLoading.../div} Routes Route path/ element{HomeApp /} / Route path/about element{AboutApp /} / Route path/dashboard element{DashboardApp /} / /Routes /Suspense /div ); }2. 使用 Single-SPA// 正确姿势使用 Single-SPA // root-config.js import { registerApplication, start } from single-spa; import { constructRoutes, constructApplications, constructLayoutEngine } from single-spa-layout; // 加载路由配置 const routes constructRoutes(document.querySelector(#single-spa-layout)); const applications constructApplications({ routes, loadApp({ name }) { return System.import(name); }, }); const layoutEngine constructLayoutEngine({ routes, applications, }); // 注册应用 applications.forEach(registerApplication); // 启动应用 layoutEngine.activate(); start(); // 微应用入口 // app1.js import React from react; import ReactDOM from react-dom; import singleSpaReact from single-spa-react; import App from ./App; const lifecycles singleSpaReact({ React, ReactDOM, rootComponent: App, errorBoundary(err, info, props) { return divAn error occurred/div; }, }); export const { bootstrap, mount, unmount } lifecycles;3. 使用 qiankun// 正确姿势使用 qiankun // 主应用 main.js import { registerMicroApps, start } from qiankun; // 注册微应用 registerMicroApps([ { name: home, entry: http://localhost:3001, container: #subapp-container, activeRule: /, props: { token: your-token, userInfo: { name: user } } }, { name: about, entry: http://localhost:3002, container: #subapp-container, activeRule: /about, }, { name: dashboard, entry: http://localhost:3003, container: #subapp-container, activeRule: /dashboard, }, ]); // 启动 qiankun start({ sandbox: { strictStyleIsolation: true, }, prefetch: true, }); // 微应用 main.js import { createApp } from vue; import App from ./App.vue; import router from ./router; let instance null; function render(props) { const { container } props; instance createApp(App); instance.use(router); instance.mount(container ? container.querySelector(#app) : #app); } if (!window.__POWERED_BY_QIANKUN__) { render({}); } export async function bootstrap() { console.log(vue app bootstraped); } export async function mount(props) { console.log(props from main app, props); render(props); } export async function unmount() { instance.unmount(); instance null; }4. 微前端通信// 正确姿势微前端通信 // 使用 EventBus class EventBus { constructor() { this.events {}; } on(event, callback) { if (!this.events[event]) { this.events[event] []; } this.events[event].push(callback); } emit(event, data) { if (this.events[event]) { this.events[event].forEach(callback callback(data)); } } off(event, callback) { if (this.events[event]) { this.events[event] this.events[event].filter(cb cb ! callback); } } } // 全局 EventBus window.eventBus new EventBus(); // 微应用 A 发送事件 window.eventBus.emit(userLoggedIn, { user: John }); // 微应用 B 监听事件 window.eventBus.on(userLoggedIn, (data) { console.log(User logged in:, data.user); }); // 使用共享状态 // 共享状态管理 class SharedState { constructor() { this.state {}; this.listeners []; } set(key, value) { this.state[key] value; this.notify(); } get(key) { return this.state[key]; } subscribe(listener) { this.listeners.push(listener); return () { this.listeners this.listeners.filter(l l ! listener); }; } notify() { this.listeners.forEach(listener listener(this.state)); } } // 全局共享状态 window.sharedState new SharedState(); // 订阅状态变化 const unsubscribe window.sharedState.subscribe((state) { console.log(State changed:, state); }); // 更新状态 window.sharedState.set(user, { name: John, age: 30 });毒舌点评早这么做你的应用早模块化了。别告诉我你不知道微前端架构那你还是趁早去写静态页面吧。实战技巧前端微前端架构指南1. 微前端框架选择框架特点适用场景Module Federationwebpack 5 内置无需额外依赖同技术栈、需要共享依赖的场景Single-SPA成熟的微前端框架支持多种技术栈多技术栈、复杂应用场景qiankun基于 Single-SPA中文支持好国内项目、需要完善文档的场景Frint基于 React支持状态管理React 技术栈项目Piral基于 React插件化架构插件化应用场景2. 微前端架构设计应用拆分策略按业务域拆分用户、订单、商品等按功能拆分首页、详情页、管理后台等按技术栈拆分React 应用、Vue 应用等共享依赖管理共享第三方库React、Vue、lodash 等共享工具函数日期处理、网络请求等共享组件按钮、表单、弹窗等路由管理主应用管理全局路由微应用管理内部路由使用路由守卫控制权限状态管理微应用内部状态使用 Redux、Vuex 等全局共享状态使用 EventBus、状态管理库等跨应用通信使用自定义事件、共享存储等部署策略独立部署每个微应用独立部署统一部署所有微应用一起部署CI/CD自动化部署流程3. 最佳实践保持微应用小而专注每个微应用负责特定的功能合理共享依赖避免重复加载第三方库统一设计系统确保微应用之间的视觉一致性完善的错误处理微应用故障不影响主应用性能优化按需加载微应用预加载常用微应用缓存微应用资源监控和日志统一的监控和日志系统安全措施隔离微应用的 DOM 和 CSS防止微应用之间的恶意攻击保护敏感数据4. 常见问题及解决方案样式冲突使用 CSS Modules 或 styled-components使用 qiankun 的样式隔离功能为微应用添加命名空间依赖冲突使用 Module Federation 共享依赖统一第三方库版本使用 webpack 的 externals 配置性能问题按需加载微应用预加载常用微应用优化微应用的打包体积通信问题使用 EventBus 进行事件通信使用共享状态管理库使用 URL 参数传递数据部署问题统一的部署流程版本管理和回滚机制环境配置管理前端微前端架构不是可选的是未来的趋势。别再把所有功能都放在一个应用里了——模块化一下你的应用会更易于维护。微前端架构就像一个大型购物中心每个店铺都是一个独立的微应用顾客可以自由穿梭于不同的店铺而整个购物中心保持统一的管理和体验。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2453737.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!