Jan 31

小议:块协议驱动GUI开发(Block Protocol)

Lrdcq , 2022/01/31 01:02 , 程序 , 閱讀(1922) , Via 本站原創
最近有老外建立了一个新的项目,Block Protocol(https://blockprotocol.org),暂时简称“块协议”,目前还处于非常前期的阶段。它提出了一种思路与面向Web GUI的方案,通过块协议标准化的GUI块搭建应用与数据驱动逻辑,来构成人类与机器均友好的GUI应用。

听起来和一般我们所说的组件式或者模块式开发并没有什么不同,但是从块协议本身的视角,协议比实现更有价值,因此小议下blockprotocol的零零碎碎。

blockprotocol提出思路

根据blockprotocol团队的描述(https://www.joelonsoftware.com/2022/01/27/making-the-web-better-with-blocks/),他们的idea来自各种主流cms系统,如Wordpress——我们可见的大部分网站都是以信息块的方式进行组织的,而大部分cms系统都会将信息块进行抽象,变成一个一个小的widget的,通过组合和嵌套来完成整个网站。当然,每一个cms系统都会有自己定制的widget体系,也包括一定的widget市场这样的东西。那么我们可以试想,能否有一种互联网业界通用的widget,来填充页面的block,通过不同的block组合来完成整个GUI开发。
點擊在新視窗中瀏覽此圖片
因此他们提出了blockprotocol,暂时翻译为块协议。块协议的重点放在了协议即protocol上,励志于建设一种通用的协议与一个目前可行的方案,来让WebGUI服务可以以block的方式进行组织

为什么不是组件

上文的描述看起来blockprotocol不就是一套通用组件么?或者说是Web Components也能解决这个问题。为什么要单独设计一套blockprotocol,而且目前的实现还low得一匹?

这里的核心问题是,blockprotocol解决的不是GUI应用开发过程的组织方式,而是GUI应用本身的组织方式。

GUI应用在不同系统与环境中有大量不同的组织方式。比如Android则是以四大组件为单位提供的应用,Activity页面,Service后台服务。iOS则是以应用ipa为单位提供的服务,后来发现不够用开始有了各种extension。Web应用是以“页面”与“域”为单位进行组织的,一个页面内一定是一个独立的应用,当然我们也发现页面为单位在Web上完全不不够用的,因此从上古开始就有frame的“子页面”形式应用组织,现在各种独立的worker也能构成独立的后台服务,包括目前大家在寻求的web微应用嵌入方案,也是在尝试继续缩小gui应用。

blockprotocol想做的,就是更进一步,将应用的边界范围继续缩小,变成界面块为单位的应用组织方式,来实现更自由的WebGUI环境。

block的描述与通用性

在block的描述与使用层面,它确实更应该像是一个组件。目前blockprotocol建设的demo是基于react的,因此一个block看起来有如下描述:
//文档类型描述 from demo https://github.com/hashintel/hash/blob/main/packages/blocks/code/package.json
  "blockprotocol": {
    "displayName": "Code",
    "icon": "public/code.svg",
    "image": "public/preview.svg",
    "examples": [
      {
        "caption": "A JavaScript code example.",
        "language": "javascript",
        "content": "function debounce(func, timeout = 300){\n  let timer;\n  return (...args) => {\n    clearTimeout(timer);\n    timer = setTimeout(() => { func.apply(this, args); }, timeout);\n  };\n}"
      }
    ]
  }

对于单个block应用本身的描述,如名称icondoc等基本信息。当然从笔者来看,缺少一个非常关键的信息,即host或者url来表明block服务来源。目前开发中的demo之所以没有这个概念,是因为所有的block目前都基于blockprotocol自己网站进行发布,然而如果预期是一个开放的protocol,一定是一个基于url等信息加载的block,一定就需要服务提供者唯一信息了。同时基于host也能延续web的域安全策略。

当然,每一个block如果视为组件,一定有数据的输入输出,在React形式下,这个组件的输入输出看起来并没有什么不同:https://github.com/hashintel/hash/blob/main/packages/blocks/code/src/App.tsx。如果输入输出能够统一,那么协议本身就已经实现完备。

每一个block app目前会打包为一个js文件,可以通过源码形式的引入就像使用普通的组件那样,或者直接在运行时引入js文件,加载在现有的spa应用中,这是更符合预期的使用方式,看起来url如https://blockprotocol.org/api/blocks?json={"name":"Bob","email":"bob@test.com"}。

当然,作为独立应用,一个block的运行还有以下关注点:

a. 输入输出安全性:协议的输入输出对象都是可序列化的基本数据,与基本的事件响应,可以被proxy或者产生行为穿透的数据都会被过滤。

b. 沙盒运行时:block应该绝对不可能访问到宿主的任何上下文。block的行为不应该对宿主有直接影响(比如layout变化)。

c. 机器可读性:在实际呈现的GUI结构及html结构中,block应该是有明确语义的。这样才能通过爬虫发现服务的内容。

目前遇到的瓶颈

很显然,满足以上要求的blockprotocol,若不是浏览器直接提供支持,一定需要一个非常厚重的js runtime——这就是目前blockprotocol实际给到我们的东西。

另外在协议组织,安全性,等方面面临几个大问题:

a. 布局协议组织:如果最小应用单位是页面,那么我们只需要完成页面之间的通信与路由就可以组织起不同应用。而如果最小单位是block,那么组织起block的是通信与布局。如何设计出一个通用并且实际GUI可用的布局穿透方式会是这个协议的大难点。目前的实现方案是和普通的css组织的组件一样,放在一起随意排列(实际上应该是wip中),但是显然这种无协议直接穿透的方案从通用性与安全性看都不是长久之计。

b. 沙盒:目前要在js中实现一个正式的html沙盒(而不是纯粹的js沙盒)的方案基本上是基于iframe的,但是其中的运行时通信转换成本确实太大了。自然而然的基于host进行组织是可能的将来的方案。但是对于除了Web以外的GUI方案中,则会更困难(如小程序)。

c. 协议跨平台:理想的情况下,这个协议至少从设计上是跨平台的,但是目前整个设计还是以Web的SPA应用为切入口的,因此下一步还是得从普通Web页面下手,尝试设计出所有GUI通用的跨平台协议,再逐个平台进行实现。

blockprotocol会是未来么

目前的blockprotocol绝不是未来,显然——如此厚重的运行时方案不太可能直接使用在生产环境,除非生产环境本身就是基于blockprotocol进行搭建并且确实已经有足够的厚重程度了。然而对应的,我们确实一直在寻找继续缩小GUI应用来继续完成现有服务的组织方式的方案。

因此给到的todo是:

1. 目前的blockprotocol看看就好,不要进行block(widget)开发, 不要使用。
2. 等待W3C的Web Components服务化,参与W3C标准讨论串尝试推进相关议题。
3. 继续在现有的框架内,推进组件标准化,双向奔赴。
logo