微前端
是一种类似于微服务的架构,它将微服务的理念应用于浏览器端,即将单页面前端应用由单一的单体应用转变为多个小型前端应用聚合为一的应用。各个前端应用还可以独立开发、独立部署。同时,它们也可以在共享组件的同时进行并行开发——这些组件可以通过 NPM
或者 Git Tag、Git Submodule
来管理。
前后端不分离 > 前后端分离 > 微服务 > 微前端
显然,我们需要更复杂的方法,将单独开发的用户界面小组件组合成一致的前端界面。这可以算是分布式 web 应用演进的下一步。
微前端和组件、模块的关系是什么?这是一个好问题。这些概念都意味着通过拆分单元的方式让代码更易复用,更易归责。唯一的差别是层次不同:
组件构成界面库。
模块构成相应的运行时。
包构成依赖关系。
微前端构成呈现的应用。
因此,如果把微前端比作器官,那么包就相当于细胞,模块就相当于分子,组件就相当于原子。
为什么要用微前端
采用微前端的原因有许多种,经常主要是为了技术本身,不过,理想情况下,采用微前端是基于真实业务场景,或是出于改善用户体验的需要。
微前端方案的核心在于追求以下特性:
前端各部分可以单独开发、测试、部署。
前端各部分的增加、移除、替换无需重新构建。
前端各部分可以采用不同的技术。
因此,微前端的精髓在于解藕。应用达到特定规模后,微前端开始变得有意义。其中一个好处是更多潜在的团队划分可能性,包括组建更小的全栈团队。
微前端和全栈团队
在满足以下一项或多项条件时,微前端值得考虑:
多个团队贡献前端代码
面向特定用户或用户组激活、关闭、推出前端的某一部分
允许外部开发者扩展用户界面
用户界面每天或每周都会加入新特性,同时又不能影响系统的其他部分
在应用增长的情况下保持开发速度恒定
不同团队能够使用自己的工具
谁在用微前端
有越来越多的公司正在使用微前端;
如何构建微前端
很不幸,这个有趣的问题只有一个含混的答案:就像微服务一样,并不存在适用于所有人的单一方法,也没有业界标准。
不同于微服务,微前端引入了基本性的差异,而不仅仅是实现细节上的差异。所以,我们需要区分微前端的使用范围。一些服务端框架也允许客户端复合(client-side composition),不过,相反的情况也是成立的。
微前端的实现,意味着对前端应用的拆分。拆分应用的目的,并不只是为了架构上好看,还为了提升开发效率。
为此,微前端带来这么一系列的好处:
-
应用自治。只需要遵循统一的接口规范或者框架,以便于系统集成到一起,相互之间是不存在依赖关系的。
-
单一职责。每个前端应用可以只关注于自己所需要完成的功能。
-
技术栈无关。你可以使用 Angular 的同时,又可以使用 React 和 Vue。
除此,它也有一系列的缺点:
-
应用的拆分基础依赖于基础设施的构建,一旦大量应用依赖于同一基础设施,那么维护变成了一个挑战。
-
拆分的粒度越小,便意味着架构变得复杂、维护成本变高。
-
技术栈一旦多样化,便意味着技术栈混乱。
微前端应用间的关系来看,分为两种:基座模式(管理式)、自组织式。分别也对应了两者不同的架构模式:
-
基座模式。通过一个主应用,来管理其它应用。设计难度小,方便实践,但是通用度低。
-
自组织模式。应用之间是平等的,不存在相互管理的模式。设计难度大,不方便实施,但是通用度高。
从技术实践上,微前端架构可以采用以下的几种方式进行:
-
路由分发式。通过 HTTP 服务器的反向代理功能,来将请求路由到对应的应用上。
-
前端微服务化。在不同的框架之上设计通讯、加载机制,以在一个页面内加载对应的应用。
-
微应用。通过软件工程的方式,在部署构建环境中,组合多个独立应用成一个单体应用。
-
微件化。开发一个新的构建系统,将部分业务功能构建成一个独立的 chunk 代码,使用时只需要远程加载即可。
-
前端容器化。通过将 iFrame 作为容器,来容纳其它前端应用。
-
应用组件化。借助于 Web Components 技术,来构建跨框架的前端应用。
按业务拆分与微服务类似,要划分不同的前端边界,不是一件容易的事。就当前而言,以下几种方式是常见的划分微前端的方式:
-
按照业务拆分。
-
按照权限拆分。
-
按照变更的频率拆分。
-
按照组织结构拆分。利用康威定律来进一步拆分前端应用。
-
跟随后端微服务划分。实践证明, DDD 与事件风暴是一种颇为有效的后端微前端拆分模式,对于前端来说,它也颇有有效——直接跟踪后端服务。
bit是一种类似于npm的包/组件公共库,是开源的命令行工具。用来解决跨项目和跨仓库的组件协作。由于npm发布的资源、数据全部都是公开的,所以对项目的部分源代码并不适用。
同时,bit提供了私有集合,私有集合与公开集合的使用并无任何区别,但是只有管理者(master)与受邀请的开发者(developer)能使用。bit允许每个用户创建一个免费的私有集合。若需要更多的私有集合,需要交付月金。
bit可以将分散在各个项目中组件分发到独立的可重用的包中,您可以设置自己的服务器来进行组件协作,也可以使用bit.dev云托管进行私有和公共组件共享。
BIT开发文档地址: https://docs.bit.dev/docs/quick-start
兼容多语言管理:
- 公用组件、代码片段便捷发布
- 公共组件、代码片段便捷导入
- 公共组件、代码片段版本控制
- 公共组件、代码片段快速索引及选用(实时编译、实时预览)
- 公共组件、代码片段自动测试执行
- 公共组件、代码片段文档生成
- 结合配置CI自动完成NPM发布
- 标准化开发规范
组件,简单点说就是可重复使用的代码段,包含但不限于:
- React、Vue、Angular 组件
- 公共样式文件,如 CSS、SCSS 文件
- 重复使用的函数、方法
1.安装BIT:
sudo npm install bit-bin -g
sudo yarn add bit-bin -g
2.选择你想要使用Bit的项目目录,在项目目录中初始化BIT工作空间
cd prodect
bit init
自测写了个例子
跟踪操作将本地项目中的一个或多个文件转换为了 Bit 组件,然后会保存上面提到的三个元素。
bit add <file_path> --id <component_id>
如:bit add src/components/button/button.vue --id button
如果一个文件内通过 require
或 import
引入了另一个文件,只需将它们一同跟踪,Bit 会自动分析他们之间的依赖关系:
bit add src/components/father.vue src/components/son.vue --id father-son
也可直接跟踪一个目录下的所有组件:
bit add src/components/* --namespace hello
跟踪后修改完成,可以打包,或不打包直接tag,都可
bit build <build_name>
3. 设置组件版本:
bit tag --<component_id> <version>
执行此操作后 Bit 会锁定该组件的依赖项版本,运行编译并测试该组件(可使用 --verbose
选项查看组件测试结果),如果编译测试通过则会设置组件的版本并自动标记依赖于该组件的组件。
使用 :
bit untag <component_id> <version>
命令可取消设置的版本号。
4. 导出组件
在 bit.dev 中申请账号
创建一个公共的或私有的集合,用以存储组件
在项目中使用 bit login
登录,Bit 会自动打开浏览器进行身份验证
bit login
发布组件:
bit export <user_name>.<collection_name>
查看远端组件库:
bit list
查看环境配置是否通过
bit doctor
安装及使用组件:
如果将组件发布至 bit.dev,那么使用 NPM 或者 Yarn 是在其它项目中最方便快捷安装使用 Bit 组件的方式,安装组件的命令位于 bit.dev 中组件页面的右上角。
npm config set @bit:registry https://node.bit.dev
如果需要安装私有组件,请使用npm login
npm login --registry=https://node.bit.dev --scope=@bit
然后就可以像 NPM/Yarn 安装第三方包一样安装 Bit 组件了
npm i @bit/other.components.button
yarn add @bit/other.components.button
测试效果:
导入组件:
导入组件指将远程组件的所有信息下载到本地,包括组件的源代码、依赖项等,导入的文件位于配置文件 package.json
中 componentsDefaultDirectory
项定义的目录中。
bit import <user_name>.<collection_name>/<component_id>
弃用或删除组件:
弃用组件意味着 Bit 会将其标记为“已过时”,但不会影响组件正常使用。
bit deprecate <user_name>.<collection>/<component_id> --remote
删除一个组件需要考虑是否有其它组件依赖此组件,所以一定要慎重操作。
bit remove <user_name>.<collection>/<component_id> --remote
Bit Server 就是 bit.dev 的代替工具了,且是超低配版,它能提供的功能只有作为“远程仓库”来存储组件,本地通过 SSH 来与 Bit Server 通信,发布和导入组件就相当于 Bit Server 的存和取操作了。相对的,功能不健全但成本也相对较低,要使用 Bit Server 只需要一个服务器就够了。
常用命令:
Command | Function | Options |
---|---|---|
bit init | 初始化 Bit 环境 | --package-manager :设置包管理工具 |
bit login | 登录到远程 | |
bit logout | 注销已登录账号 | |
bit list | 显示远程和本地所有组件 | |
bit status | 查看工作区中被跟踪组件的状态 | |
bit add <file_path> --id <component_id> | 追踪组件 | --id :指定组件 ID--namespace :设置命名空间--exclude :排除文件 |
bit untrack <component_id> | 取消追踪组件 | |
bit show <component_id> | 查看组件的依赖关系 | |
bit diff <component_id> | 比较更改前后组件的变化 | |
bit log <component_id> | 查看组件各版本信息 | |
bit tag <component_id> <version> | 设置组件版本号 | --message :版本描述--all :为所有新增和修改的组件设置 |
bit untag <component_id> <version> | 取消设置的版本号 | --all :取消设置的所有组件的版本号 |
bit export <user_name>.<collection_name> | 导出到远程 | --eject :导出后将本地代码替换成该组件--all :导出所有 |
bit import <user_name>.<collection_name>/<component_id> | 导入组件 | |
bit deprecate <component_id> | 弃用组件 | --remote :同时从远程弃用 |
bit remove <component_id> | 删除组件 | --remote :同时从远程删除 |
总结:
首先,Bit 的确是为前端组件化、代码片段管理提供了一套不错的解决方案,如果组件都能跨项目地去使用,而且只需要一行 Bit 命令就可以解决,既保证了开发的高效性,也能保证组件的整体质量及可复用性。
如果前端的工作方式都切换到 Bit 模式上,那么从发布方式、规范化、标准化等方面来说就没得挑,因为你发布的组件别人要用得上、可以用、用得爽啊!所以,从这里来看 Bit 的确可以规范前端组件标准,有效解耦前端代码。
但是,以 Bit 目前的知名度和普及度来看,它还有很长的路要走,这也不是没有原因的:
-
bit.dev 不开源,自行搭建的 Bit Server 功能实在是太有限了,
-
Bit 没有像 GitHub、GitLab 这样的可以以项目为单位管理组织代码的机制,以至于看起来像是 Codepen 这样的交流社区。
-
权限管理功能欠缺。