你可能不需要微前端,但你一定会需要微内核

先聊聊微前端

阿里巴巴的一篇 为iframe正名,你可能并不需要微前端 又将社区的风向一转,当初大力推销微前端概念的阿里巴巴又主动跳出来说微前端未必好用。

虽然不知道阿里巴巴内部发生了什么,但是同样作为一名在工作中深度使用微前端框架的前端码农来说,我想我也逐步触及了微前端的限制。

微前端,简单来说就是把原来iframe实现的隔离机制用js实现了一遍。其背景是为了解决多个团队同时修改一套系统可能带来的项目管理问题,

而微前端的好处在于,iframe的隔离是完全隔离,而微前端是一个可控的隔离。即在某些情况下可以分享一些内容。

微前端的架构往往是由一个基座项目为中心,加上若干个子项目组成。而子项目与子项目之间有一些内容是可以共享的,比如说组件库,公共依赖,缓存管理,权限管理等。这是微前端给我们带来的好处与优势。而曾经的iframe方案则很难做到这一点。

至于iframe方案和微前端的方案的优劣在此不再赘述,但是我想带大家了解一下更容易被我们忽略的东西

什么是微内核

在了解了什么是微前端后,我想向大家介绍一下微内核的概念。

什么是微内核?即以一个核心服务为中心,然后将所有的业务当做一个可插拔的插件。

这种架构是不是非常眼熟?没错我们经常用的 vscode 也是这样的微内核框架,vscode 的核心就是一个文本编辑器,然后配套上一个拓展中心用于加载插件。

而像是主题、语言支持、格式化工具以及各种第三方工具面板,都是一个个独立的外部插件。正是因为完整的插件生态造成了 vscode 的成功。而 vscode 的插件系统就是一种微内核架构。

而回过头想想,微前端又何尝不是一种特殊的微内核解决方案呢?微前端无非是基于路由的、限定同时只能加载一个子应用(插件),具备沙盒机制的微内核框架。

微内核架构可以给我们带来什么

在谈论微内核架构时,我们得先抛开一切上下文。聊聊微内核架构的设计理念。

将系统的实现,与系统的基本操作规则区分开来。它实现的方式是将核心功能模块化,划分成几个独立的进程,各自运行,这些进程被称为服务。所有的服务进程,都运行在不同的地址空间。

让服务各自独立,可以减少系统之间的耦合度,易于实现与除错,也可以增进可移植性。它可以避免单一组件失效,而造成整个系统崩溃,内核只需要重启这个组件,不至于影响其他服务器的功能,使系统稳定度增加。同时业务功能可以视需要,抽换或新增某些服务进程,使功能更有弹性。

就代码数量来看,一般来说,因为功能简化,核心系统使用的代码比集成式系统更少。更少的代码意味更少的潜藏程序bug。

在长期使用微前端的过程中我们也能发现其好处,业务代码再怎么发生改变,也不会影响整体系统的稳定性。而相比于微前端,微内核的设计抽象度会更加复杂一点,相对的,两者的交流也会更加频繁一点,自由度也会更加高。

相比于微前端固定位置,共享部分依赖的简单场景来说,微内核的核心系统会更加复杂一点。我们依旧是以 vscode 为例, vscode 需要抽象化他的核心系统,可以支持各种插件的功能,比如为系统的各个内容、token做标记,以支持各类主题的接入。为各种语言服务做抽象层,以兼容不同语言的需求等等。

这也是为什么这类做插件系统的应用很少。因为虽然大家都知道插件系统能够带来各种各样的好处,但是因为设计的复杂性导致愿意去做的人比较少。当然,这个复杂度是针对核心系统的,对于插件的开发者来说并不会感知到,而是可以直接使用成熟的核心系统提供的能力快速进行开发。相信开发过 vscode 的同学都不需要了解内核系统是怎么运作的。

当然,在日常的使用我们也有用到微内核的概念。常见的例子就是各类orm支持不同的数据库,然后我们通过一个适配层将通用的orm根据不同的数据库实现进行适配。

再比如飞书文档支持各类第三方内容块,而这些第三方内容块就是一个个插件。只需要统一的协议来约定交互行为即可。

所以为什么我说我们需要微内核架构呢?微内核架构更多的是一种设计思路,很多时候我们愿意去写集成式的应用,往往随着代码的迭代整个系统的复杂度越来越高、越来越难以维护。变成一个巨石应用,也往往被后来的维护者称为屎山代码。而如果我们前期就做好一定的抽象,那么随着时间而增加的代码复杂度的增长幅度也会逐渐趋于稳定。

那么有什么实现微内核架构的库呢

当然有。

mini-star(https://ministar.moonrailgun.com/) 就是一个可以满足想要构建微内核架构的库。

mini-star 只做一个微内核库该做的事情,即插件构建、加载、与依赖共享。

相比于微前端的基于路由的、同时只能运行一个子应用的限制,mini-star 并没有对开发者做任何的限制,也就是说并没有做任何预设的场景限制。如微前端因为其限制更多的还是用在后台应用上,而作为微内核库的 mini-star 则可以用在任何场景。

mini-star 提供了运行时加载器(runtime), 插件编译器(bundler) 和命令行工具(cli)。从全链路支持插件系统的开发。

编译生态

mini-star 的编译器依托于 Rollup 。因此可以直接复用现成的rollup生态对代码做优化。当然 mini-star 已经内置了一部分常用的编译插件,开箱即用。

懒加载

mini-star 的内核加载系统约定了插件和加载器运行时的规则,在运行时统一采用了类amd加载策略,因此依赖是可以收集以及被感知的,一个插件编译产物的结构如下:

源文件

1
2
3
4
// 源文件:
import "@capital/any";

// some logic
1
2
3
4
// 编译后的文件:
definePlugin('@plugins/foo', ['@capital/any'], (function (any) {
// some logic
}));

因此, mini-star 支持依赖懒加载,而如 qiankungarfish 这种使用webpack的external机制进行共享的微前端框架是不支持的。

1
2
3
4
regSharedModule(
'@capital/any',
() => import('./any')
);

更多的可以访问 mini-star 官网了解更多: https://ministar.moonrailgun.com/

文章目录
  1. 1. 先聊聊微前端
  2. 2. 什么是微内核
  3. 3. 微内核架构可以给我们带来什么
  4. 4. 那么有什么实现微内核架构的库呢
    1. 4.1. 编译生态
    2. 4.2. 懒加载