7

基于Jenkins、Figma插件实现原理探究web系统插件化架构

 2 years ago
source link: https://ranying666.github.io/2021/06/15/web-plugin-artch/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

背景:对于大型web应用而言,功能极其丰富复杂,为了具备扩展性,部分项目选择插件化架构方式,开放一部分系统Hook给具备开发能力的用户,不但提升用户的体验感,还同时丰富平台功能,一举两得。如何构建具备插件化能力的平台?本文尝试通过分析jenkins jar包插件实现方式及Figma前端插件实现方式探究插件化架构方案。

我们常见的支持插件化的应用是一些桌面端编辑器,如VSCode,Eclipse,Idea,Sublime等,也有支持动态扩展的web应用,如构建工具Jenkins,支持前端插件扩展的web应用,如设计工具Figma。不管哪种应用方式,基本的设计逻辑大致如下。

%E6%8F%92%E4%BB%B6%E7%B3%BB%E7%BB%9F%E9%80%9A%E7%94%A8%E6%96%B9%E6%A1%88.png

我们当前主要研究的是web系统的插件化构架方案,本地插件化软件先不讨论。主要以jenkins和figma的两种实现方式进行探讨。

Jenkins插件化系统

10.png

Jenkins可以支持git, svn, maven等很多功能,这些都是Jenkins的插件,Jenkins通过扩展点及前端视图模板来提供插件扩展能力,以jar包的方式上传到指定目录,创建类加载器 class-loader,使用插件策略PluginStrategy加载可以激活的插件。

(一)扩展点

Jenkins有很多的扩展点ExtensitonPoint),它是Jenkins系统的某个方面的接口或抽象类。这些接口定义了需要实现的方法,而Jenkins插件需要实现这些方法,也可以叫做在此扩展点之上进行扩展Jenkins。有关扩展点的详细信息,请参阅Jenkins 官方ExtentionPoints文档。通过这些扩展点我们可以写插件来实现自己的需求。
下面是一些常用的扩展点:

  • Scm :代表源码管理的一个步骤,如下面的Git,Subversion就是扩展的Scm

    11.png

  • Builder : 代表构建的一个步骤,如下图中在构建过程中,我们可以增加一个构建步骤,而每一个选项都是对应一个Builder,在每一个Builder中都有自己不同的功能。如Execute shell,这就是一个ShellBuilder,意味着在构建过程中会执行一个shell命令

12.png

  • Trigger:代表一个构建的触发,当满足一个什么样的条件时触发这个项目开始构建。比较常用的触发就是当代码变更时触发,如果我们需要实现一些比较复杂的触发逻辑,就需要扩展Trigger这个扩展点

    13.png

  • Publisher:Publisher代表一个项目构建完成后需要执行的步骤,如选项中的E-Mail Notifaction就是一个Publisher插件,选择这个选项后,当项目构建完成,就会使用email来通知用户,假如想要在项目构建完成后将构建目标产物发送到服务器上,则可以扩展此扩展点。

    14.png

(二)Jenkins中的视图

Jenkins 使用jelly来编写视图,Jelly 是一种基于 Java 技术和 XML 的脚本编制和处理引擎。Jelly 的特点是有许多基于 JSTL (JSP 标准标记库,JSP Standard Tag Library)、Ant、Velocity 及其它众多工具的可执行标记。Jelly 还支持 Jexl(Java 表达式语言,Java Expression Language),Jexl 是 JSTL 表达式语言的扩展版本。Jenkins的界面绘制就是通过Jelly实现的。

另外一个开源的插件化后台管理系统:grape: 前后端可插件开发的后台管理系统 (gitee.com)

Figma前端插件系统

Figma 是一个在线协作式 UI 设计工具,具有插件扩展功能,只要有前端开发能力的用户均可开发自己的插件来扩展设计体验。

image-20210611163806313.png

Figma的插件是纯前端的插件方式,没有后端代码,它的插件系统是如何工作的?

这是一个基于 TypeScript + React 技术栈,使用 Webpack 构建的 Figma 插件目录结构如下:

├── README.md
├── figma.d.ts
├── manifest.json
├── package-lock.json
├── package.json
├── src
│ ├── code.ts
│ ├── logo.svg
│ ├── ui.css
│ ├── ui.html
│ └── ui.tsx
├── tsconfig.json
└── webpack.config.js

在其 manifest.json 文件中包含了一些简单的信息。

{  
"name": "React Sample",
"id": "738168449509241862",
"api": "1.0.0",
"main": "dist/code.js",
"ui": "dist/ui.html"
}

可以看出 Figma 将插件入口分为了 mainui 两部分, main 中包含了插件实际运行时的逻辑,而 ui 则是一个插件的 HTML 片段。即 UI 与逻辑分离。 main 中的 js 文件被包裹在一个 iframe 里加载到页面上。而 ui 中的 HTML 最终也被包裹在一个 iframe 里渲染出来,这将有效的避免插件 UI 层 CSS 代码导致全局样式污染。

ui展示是通过如下代码加载,会弹出个DIV,展示manifest.josn中指定的ui地址内容:

figma.showUI(__html__);

在上一层使用 window.addEventListener进行监控,事件通信使用 parent.postMessage,发送事件及数据。figma使用了两层iframe来嵌套装载插件内容。

我画了架构图来描述,大致如下:

Figma%E6%8F%92%E4%BB%B6%E7%B3%BB%E7%BB%9F.png

开发的插件可在本地app中进行调试,最终发布到服务器。

image-20210611171346786.png

image-20210611171419422.png

插件系统在设计时要考虑的基本内容,如何开放数据接口,如何加载插件,何时何地启动插件,插件如何与主程序通信问题,如何保证插件安全性?前端插件化使用iframe sandbox是一个通用可行的办法,但依然会有很多问题。

How Plugins Run · Figma Developers

Figma 插件开发 101

大型 Web 应用插件化架构探索

iframe参考

window.postMessage


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK