最近在公司设计了插件平台架构,我之前写的Rallie.js(源码解读文章烂尾了)也非常适合用来做插件架构,两次实践让我对该领域略有心得,在此分享。
文章内容主要是聊设计原则,没有具体的代码实现
为什么需要插件架构
需要插件架构的往往是国内SaaS产品,国内SaaS企业做到一定规模,很难避开的一个场景就是客户定制。面向海外市场的SaaS,产品力比较重要,用户为了击中他们爽点的设计买单,本质上更像C端市场。而在国内,产品的灵活性比较重要,很多企业往往并不需要你提供一个标准简洁的最佳实践,而是需要你的产品能帮助他们解决内部已有系统的痛点,否则用户的续费概率往往很低。
海外SaaS为爽点买单,国内SaaS为痛点买单
正是因为这个区别,导致国内做SaaS的企业到了海外往往水土不服,很难生存。因为在客户定制的土壤下生长起来的产品很难不受定制企业的影响,从而充满了各种非标设计,使产品力直线下降。
如果有一个插件平台专门用来承载客户企业的定制需求,那就可以将客户企业对标准产品的影响降到最低,有利于产品摸索出最简洁又实用的SaaS产品
设计的取舍
在插件架构设计中,我总结出一个不可能三角:
- 较低的设计与实现难度
- 较丰富的功能
- 较好的安全性
最多只能实现两个。
举个例子,在设计前端插件平台时,要相对容易地实现一个「让页面中的任意一个位置都支持注入插件代码进行定制」的系统,那么就只能运行受信任的插件代码。如果要运行不受信任的插件代码,只能放弃「让页面中的任意一个位置都支持注入插件代码进行定制」的诉求,规定一个或几个相对固定的区域安全地执行插件渲染逻辑。而如果想要实现安全性与丰富性兼得,那就需要处理沙箱运行,平台与插件之间数据的安全传递等问题,那么设计难度就会陡然飙升。
在这里,我说的「设计难度」是实现API友好的架构的设计难度,而非单纯「完成设计」的难度。因为要与隔离环境交换数据往往有很多限制,所以要实现丰富的功能要绕很多弯路,常常设计出让插件开发者使用起来非常麻烦的API,系统的复杂度并没有被良好的设计隐藏起来,而是外露给了插件开发者,这会影响插件生态的繁荣。
另外想格外聊一聊安全,谈到安全,其实只有「安全」和不「不安全」两种状态,因为「不绝对安全就是绝对不安全」,所以在前端插件设计中,要保证安全往往只能采用iframe或者其他worker线程的方案,目前很流行的proxy沙箱方案在保证安全方面其实是比较鸡肋的。
很多架构设计者往往没有明确自己设计的边界,什么都想要,但是这样的结果往往是什么都做得不够好,最后沦为平庸的设计。
插件生态的取舍
很多错误的设计源于错误的起点,很多程序员往往从技术角度出发去设计而非业务场景的角度。这是不对的。
在设计插件架构时,我们要考虑的第一个问题应该是我们的业务需要什么样的插件系统。
第一种情况,我们希望插件系统帮助我们接住客户千奇百怪的定制需求,那我们应该考虑建立面向内部开发者的插件生态,此时可以认为插件代码是可信任的,那么我们的架构设计应该聚焦于提供丰富的可定制功能,我们称之为封闭插件生态
第二种情况,我们希望的是系统中有一个插件市场,外部开发者可以在插件市场发布与售卖插件。那我们就必须考虑安全问题,做出的妥协就是插件将无法随意定制我们的系统,而是只能在我们限定的有限范围内运行,同时由于js不提供共享内存机制,因此插件与系统的通信也是受限的,不适合提供太复杂的功能,我们称之为开放插件生态。
我认为,封闭插件生态更适合国内SaaS环境。在封闭插件生态中,产品的售卖形式将会是:
- 对于SaaS用户:交付core product,不接受定制
- 对于有定制需求的私有部署用户:
- 较低售价:由SaaS软件提供商提供插件,交付core product + plug injector + plugin
- 较高售价:由客户方自行编写插件,SaaS软件提供商交付core product + plugin injector (之所以价格更高是因为这种售卖模式下,客户将只会付费一次,而上一种售卖方式下,客户可能会多次购买插件,这种定价策略有助于引导用户多次付费)
需要澄清的是,即使我们允许客户自行编写插件,也应该认为插件代码是可信的,因为此时用户拥有软件资产的所有权,应该由客户自行保证插件的安全性。而SaaS部署时,软件资产的所有者是SaaS服务提供商,客户仅有软件的使用权,此时插件的安全性必须由我们保证,在我们的插件架构完全信任插件代码的前提下,不适合开放插件功能,如果确实有开放插件市场的需要,则必须有完善的插件审核机制。
开放插件生态往往需要产品本身足够强势,有足够用户量,这样才有可能形成繁荣的插件生态,比如Figma的插件生态。对于很多细分领域的SaaS产品来说,这条道路或许并不适合。
总结
插件架构很适合国内SaaS供应商解决客户定制问题,在架构时需要根据业务场景做好权衡。
Rallie.js适合帮助开发封闭插件生态的插件系统。
码字不易,欢迎转载,注明出处