微前端之四 • Single SPA 的源码实现
深入了解一个库最好的办法是直接去看源代码,学习作者的设计模式、运行原理、代码风格等。并且动手跑起来,碰到不懂的地方打断点或者打印关键信息,一步一步去琢磨。
很多流行库发展多年后,优化工作越做越好,但同时会变得比较臃肿,代码量大且文件分散,直接看最新版本的源代码可能无从下手。我是这么实践的,先去看它的第一个发行版,一般来说首次发行版的代码简洁,设计模式和原理与后面的版本不会有太大的变化。
Single SPA 的1.0.0 版本是7年前发布的,只有一个文件,一共不到400行代码,非常方便阅读。Github 选择 branch 的地方有一个 tags 的选项,点开可以看到每个版本对应的源码。我克隆了一份放在自己的 Github,加上了注释,并且添加了更容易理解的接入样例,地址:https://github.com/WinjayYu/the-single-spa
根目录下面的 index.html 相当于基座应用,这里作了简化处理。首先需要引入 System.js 模块加载器,它支持动态引入 js 模块。
我们平时使用 webpack 开发的时候,所有的组件在打包后就已经变成了非模块化的 js ,所以无论浏览器是否支持模块加载都可以顺利执行。随着 ES6 的普及,越来越多的浏览器开始支持 ES Module,但是兼容性还不好,SystemJS 是现阶段下(浏览器尚未正式支持importMap)原生 ES Module 的替代品。
随后引入 Single SPA 库,然后就可以调用 declareChildApplication 注册子应用了。注册方法需要两个参数,第一个是子应用暴露给基座的配置文件,主要包括了生命周期函数;第二个是触发条件,检测当前路由是否和子应用匹配。
上图中 src/index.js 是 Single SPA 的源码,实现细节请参考 Github 仓库。下面是通过源码逻辑画的流程图,直观地展示子应用从加载到销毁的过程:
其中比较关键的是劫持 window 的 popstate 和 hashchange 监听方法 。保证 Single SPA 先感知到路由的变化,根据路由挂载指定的子应用,待子应用挂载完整后,再执行 popstate 和 hashchange 原来的监听方法。
可以看到,微前端的原理并不复杂,它其实是一种约定的架构风格。做好一件事情往往并不依赖多么前沿的技术,但需要大家的互相协作,按照统一的约定风格开发。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库