首发于字节舞者

现代 Web 开发的现状与未来(JSDC 2019 演讲全文)

本文是我受邀在台北的 JSDC 2019 活动中做的一次分享,从内容上来说已经可以算的上我的 2019 跨年演讲 XD

我比较惧怕公开演讲,习惯事先写好讲稿,虽然照稿念的演讲效果比较差,但好处是很快就可以作为文章发出来 XD(末尾部分的内容没来得及写讲稿,是临时补写的,跟现场不一样)

大家好,非常感谢主办方邀请我参加这次 JSDC 活动,让我第一次有机会跟台湾的 JS 开发者社区交流

JS 能在最近十多年里爆炸式发展到今天的程度,主要原因之一就是它建立在 Open Web 技术之上,这种技术是全行业在平台技术上最大最主要的交集和共识,JS 作为 Web 的原生语言,能力是跟 Web 本身一起不断发展的,而在 JS 生态的影响下,Web 本身和 Web 开发也都已经跟过去非常不同

我想通过几个主题来说明,如果把 Modern Web —— 也就是『现代 Web 开发』,而非『传统 Web 开发』——看作一种独立的技术范式和专业领域,它的现状是怎样的,有哪些重要趋势,未来会怎样,希望对大家有帮助

先介绍一下为什么我自己适合讲这个话题,我可能属于华语地区最早一批专业的 JS 开发者,伴随这个技术领域从几乎一无所有 —— 就是连 Firebug、开发工具甚至文档都没有的年代 —— 一直发展到今天,在这个过程中我既做过几乎所有类型的基于 Web 技术的产品,同时也一直致力于推动社区和行业向前发展,做过一些在当时属于前沿的基础建设,目前在字节跳动也仍然在负责这方面的建设(之后会讲到)

顺便说一个感言,这次来台湾对我个人还有特殊意义,因为我能进入这个技术领域,很大程度上要感谢台湾的前辈

一位前辈是朱学恒先生,在大陆的游戏圈有一期影响很大的杂志是98年大众软件增刊,朱学恒先生为这期杂志提供的介绍欧美奇幻文学、龙与地下城游戏的文章,很大程度上成为了大陆地区相关爱好者和玩家社区的起点

然后是同样来自台大电机系的几位前辈创立的奇幻修士会,他们的中文翻译让我们接触到很多被社区奉为经典的作品

我自己并非 CS 科班出身,正因为大学时加入了网上的奇幻文学和游戏社区,创立了个人网站最深的地下城,我才有机会爱上 JS 和 Web 开发,能站在这个讲台上

回到主题,其实最近几年我在各种场合都推广普及过『现代 Web 开发』的一些理念和趋势,为了保证大家掌握一样的上下文,我想先快速回顾之前做过的一些分享

首先是我发布过一个开源的文档项目《Spellbook of Modern Web Dev(现代 Web 开发魔法全书)》,基于社区经验和数据统计,汇总了现代 web 开发中各个领域的主流项目、资源和经典文章,做了细粒度的分类梳理

这个项目发布后在国际社区中传播的速度非常快,可见对这些信息的需求是非常强的,会后如果有现代 Web 开发方面的疑问,可以看一下这个项目,既可以作为新人培训的自学教材来使用,也可以当作资料库来查阅。我最近正在做一轮更新,替换里面一些过时内容

然后是在 17 年上海的 JSConfCN 上,我做过一次叫做《理解现代 Web 开发》的分享,介绍了现代 Web 开发的发展历史,引出几个重要现象

一个现象是互联网产品开发的分工模式在发生改变,传统上的分工是『水平分工』,前端开发者负责开发所有产品或程序中的前端部分,后端开发者负责所有后端部分,在有些团队和产品领域里,认为全栈开发者可以同时负责这两层

新分工模式是『垂直分工』,把人类和机器看成两个极端,在之间画一条光谱,再把这条光谱垂直切成三个频段,每个频段里的开发者,掌握的技术和关心的问题,都差别非常大,每个频段里都可能有客户端部分和服务器端部分,但对相关技术的要求不完全一样

一个应用开发者可以为『面向人类』的产品,开发专用的服务器端 API(BFF),但通常不会同时精通 NLP 和能用最专业的姿势开发分布式日志处理系统

一个分布式基础设施开发者可以在工具支持下为自己的系统添加简单的界面,但通常不适合开发用户体验要求高的大型 SaaS 应用

这种分工模式除了要求『前端开发者』成为『应用开发者』,使用更完善的 GUI 软件开发技术和工具,还衍生出来一个问题是:如何提供工具让其他垂直领域的开发者能自主搭建应用,满足这个领域中的简单 UI 需求,后面的分享内容中会再讲到这个问题

新分工模式下的应用开发者要掌握『现代 Web 开发』技术,这种技术的特征是:

不像传统 Web 开发以服务器端为主体、前端是后端 Web 框架中的一部分,现代 Web 开发是以客户端为主体,而后端部分比如 SSR、BFF、Serverless 可以成为前端框架中的一部分

因此现代 Web 开发中不止有客户端,在客户端部分,也不止有浏览器,而是面向更广泛的具备 Web Runtime 的平台(后面的分享内容中会再讲到这个问题)

第四个特征是以 JS 为中心,几乎会尽可能用 JS 解决一切问题

但在这种情况下,很多开发者都在抱怨另一个现象『JS 疲劳』,认为 JS 发展的太快,新技术、新开源项目层出不穷,用大陆的网络用语来说,就是开发者觉得心很累,没有力气再爱了

我们通过幻灯片快速看一下如何理解这种现象,它有三个根源,一个是多样性,这里说的『明年』是指 18 年

这种多样性类似美国族群的多样性,虽然理想中是『大熔炉』,现实中却常常是『沙拉碗』,社区中来自不同技术背景和行业的开发者,互相之间的融合程度非常有限,进一步放大了社区生态的多样性

第二个根源是需求多

第三个根源是成本低,包括语言本身的特点、API 的能力、以及社区生态的发展,带来的低成本能力

要解决这个问题,一方面是要掌握整体图景,前面介绍过的《现代 Web 开发魔法全书》正是服务于这种需求的项目

另一方面,前面说的「低成本」既是产生问题的原因,其实也是解决问题的方法,但前提是要普及和维护

今天我们再回头看这个问题,仍然有很多抱怨和困惑,但已经改善很多

一方面,我们在 17 年就能看到一个趋势是:现代 Web 开发的很多主流领域,技术方案已经开始稳定下来,有了明显的胜出者,前面说的魔法全书就非常重视挖掘和汇总这些主流项目

另一方面还有框架的帮助,后面的分享内容中会再讲到这个问题

我要分享的内容分成两部分,先看一些『现状』,再看『未来』

大家可能知道大陆的 CCTV 在黄金时段会播出一档很有名的、收视率很高的电视节目,叫新闻联播,接下来我也会口播一系列 Modern Web 新闻

首先是近年来,国际社区出现三个重大问题,引发了很多讨论

第一个重大问题,可以翻译成『大分裂』,说的是『前端开发者』正在分裂成没有共同语言的两个群体、完全不同的两个世界

参加今天这个活动的可能多数都是比较年轻的 JS 开发者,可能对这个问题感受比较少,感受最强烈的有两类人群:一类是很多年前开始以前端开发者的身份工作,并且满足于当时的工作方式和工作内容,另一类是因为对用户体验、UI 设计、动画、可访问性等问题感兴趣而成为前端开发者

从他们的角度来看待这个问题会更容易理解,对他们来说,『前端开发者』这个词已经完全变成另一种含义,对应的是一套完全不同的技能体系和思维方式

『前端开发者』这个词,无论在国际还是在大陆,现在都主要指图中左边的技能体系

在右边的开发者眼里,『前端开发』现在变得完全以 JS 为中心,需要掌握很多以前只有后端才需要掌握的编程知识,比如架构原则、API设计、数据模型等。曾经只要用 HTML、CSS 和少量 JS 交互就能创建 Web 界面,而这种工作现在变得复杂到不可理解。他们不理解为什么左边的人认为只会写 JS 是可以的,只会写 HTML 和 CSS 却不可以。他们觉得自己作为专家,却要被左边的人指手画脚,被强迫以左边的方式来工作

这些困惑和分歧并不能被前面提到过的『新分工模式』解决,因为我们就算抛弃了『前端』这个过时概念,但在新分工下的『应用开发』领域,仍然存在这个『大分裂』,仍然要面对如何协调左右两种思维方式和工作领域的问题

第二个重大问题可以翻译成『大困境』,指的是整个互联网行业一直致力于在设计师和开发者之间『搭建桥梁』、跨越鸿沟,让设计师的输出物能成为互联网产品的『唯一权威来源(Single Source of Truth™)』,让设计能在最终产品中被精确的还原,因此设计工具层出不穷越来越多,从 Photoshop 发展到 Sketch 再到 Figma,还有 Zeplin、InVision、Abstract 等等,设计师跟开发者一样要不断学习新工具,但是为『桥梁』付出了这么多,最主要的鸿沟和问题却始终存在

这个『大困境』的根源可能是我们的努力目标和解决方法本身有问题,也就是左侧图中的模式,大家是在现有的分工模式中做改进,在这种分工里,设计师的输出物无论如何都只能是最终产品的一种『效仿』,跟最终产品之间是割裂的

也许只有当我们承认代码才是最终产品本身,把代码作为唯一权威来源,像右侧图中这样,去解决如何让各种分工一起围绕着代码来工作,才能彻底逃脱这个『大困境』

第三个重大问题可以翻译成『大对决』,指的是『开发者体验』(DX)和『用户体验』(UX)之间的矛盾

在『大分裂』问题中,提到过一部分前端开发者认为现在的工具链已经复杂到不可理解、难以使用,而对另一部分前端开发者来说,这些现代 Web 开发领域中的工具反而极大的增强了他们的能力,也大幅提升了他们的开发者体验,但与此同时,用户体验的很多方面却没有以同样的速度发生进步,有的甚至倒退了,比如 Web 项目的依赖庞大,访问 Web 产品时需要下载的文件尺寸越来越大,等等,而如果我们要在每个局部都应用最佳实践,兼顾开发者体验和用户体验,却反过来会导致需要大量配置和调优,开发工作变得复杂,开发者体验受损

接下来,我们看下应用形态发展成了什么样子

早在移动互联网爆炸式发展之前,连线杂志就指出传统 Web 已死,而互联网会永生

既然 Web 是过时模式,App 才是未来,业界就开发了海量的 App 来解决线上线下方方面面大大小小的需求,我所在的公司字节跳动就非常擅长开发 App,被称作『App 工厂』(这张图是随便找来的,内容过时,分类也不正确)

但大家知道,几乎所有市场调查都表明,平均每个用户的手机上,大概只会保持安装 35个左右的 App,也就是说,并没有充分享受到移动互联网爆炸式发展带来的红利,而是只能接触其中很小一个局部,或只能跟很小一个局部保持联系

如果一个用户要充分享受到这些红利,要能够随时使用这些 app 来满足自己各方面的需求,他的生活会是什么样子呢

多年来,我一直在拿自己做实验,我的手机上常年保持 2000 多个 App ,幻灯片上就是前年我手机上 15 个屏幕的截屏

如果要记住这 2000个 App,在有需要的时候,快速找到最能满足需求的app,必然会造成很大的『认知负担』,所以我在实践中形成了一套方法

这种方法类似对生物物种的分类

我对所有 App 做了多级的树状分类,手机每一屏是一个『一级类别』,比如第二屏是『线下生活』,第三屏是『消费』,第四屏是『金融』

然后每一屏由『二级类别』组成,按从左到右、从上到下的流式顺序,每个类别都占据一个连续的空间,有一个自己的目录放在最后,而最常用的 App 会从目录中拖出来放到目录前面,相当于快捷入口,功能接近的 App 会连续排列在一起,形成『三级类别』

最后就形成这种结构,比如,我现在有了一个需求是买菜做饭,我要买鳕鱼,就打开手机先进入『线下生活』这个一级类别所在的第二屏,在找到『饮食到家』这个二级类别,然后打开最合适的 App,查找鳕鱼

这种使用 App 的方法,实际上重现了 Web 的早期发展:2000年前后的时候,门户网站正是用这种多级树状分类的方法,成为了互联网的入口

但区别是,在那个年代,可以由门户网站来统一维护这些分类,把大量网站都收录和连接起来,而现在市场上扮演类似角色的『超级 App』,并不能把大量 App 连接起来,只能把这些 App 的功能都自己做一遍,做到自己内部。如果要享受到市场上各种独立 App 带来的好处,只能像我这样对它们做手动管理

所以如果要充分利用这些 App 的能力,就会形成一套像物种分类一样层级很深的分类系统

幻灯片上蓝色部分是个人维护的层级,绿色部分是 App 内部维护的层级,越往下越靠近顶层

这样就会出现一个问题:最理想的用户入口在哪里

传统上,是以『品牌』为入口,比如图上中间的京东到家 App

但很多时候用户只有粗略的需求,比如我就是要吃饭,并不会刻意寻找某个品牌,这种时候,理想的入口是靠近层级顶部的,现在市场的『超级 App』,就都在向这个方向发展,让自己成为尽可能靠近层级顶部的平台,不过它们越是朝这个方向发展,其实也会越接近桌面时代的浏览器,成为一个『Web 平台』——浏览器是最顶层的平台,最大的超级 App

然后还有另一种场景,比如有同事推荐我买一种鳕鱼,这个时候理想的入口是靠近层级底部,能直接抵达『内容』或『服务』本身,而不用先打开 App,再一层层找下去,最好也不需要事先安装这个 App

所以现在大家可以发现:实际上 Web 没有死

市场上有海量的商家,包括各种提供『服务』的商家和提供『内容』的商家,它们自己开发的 App 很难成为用户的入口,入口通常是它们提供的『服务』或『内容』本身,而这种入口,其实就是 Web 的本质,想要提供这种入口能力,要么使用或发展标准的 Web 技术,要么暂时用非标准的私有实现,但随着发展演化,注定还是会向 Web 标准靠拢

一个例子是,在国际市场的两种主流方案:PWA 侧重提供『服务』,使用和发展了标准的 Web 技术,而 AMP 侧重提供『内容』,它使用了部分非标准的私有实现

AMP 这种模式引起了很多争议,Google 已经在逐步把 AMP 的能力引入到 Web 标准里,让标准 Web 具备 AMP 的能力

另一个例子是大陆市场上流行的小程序,小程序其实也是 Web 的一种非标准的私有实现,但它更针对那些提供『服务』的商家(特别是中小商家、线下商家),直接捆绑了上层的 MVVM 开发框架和工具,让这些商家可以轻易开发出能提供原生 App 体验的『Web』

随着发展演进,小程序也注定要向 web 标准靠拢,今年在北京就组织了这样的标准化研讨会

活动产出了一份 W3C 的工作草案,虽然在内容方面距离 PWA 和 AMP 的标准化还有点远,但是向 Web 标准靠拢的客观趋势是不会变的:要么把私有技术替换成已有的标准技术,要么把私有技术标准化,让标准技术具备同样的能力

所有这些解决方案,可以通称为 Web Runtime 解决方案,目前有这么几类:

第一类是 Open Web 平台,提供最标准化的技术,包括 Web 引擎(JS 和 WebAssembly 是 Web 引擎的原生语言)、Web API 和渲染引擎

第二类是『增强版 WebView(Enhanced WebView)』,在第一类的基础上,提供自定义的 API 和自定义的 UI 渲染后端

第三类可以称作『加速版移动 Web(Accelerated Mobile Web)』,AMP 和小程序表面上差别很大,本质上都属于这个类别

前三类都是基于平台级别 App 的,比如浏览器、微信、google 等超级 App,四类和第五类是基于开发工具的解决方案:

一种是 React Native 风格,基于 bridge 和 JS 线程,另一种是 Flutter 风格,基于 AOT 编译。

第六类是适合桌面平台的解决方案,把 Node.js Runtime 和 Web 平台打包在一起

前面说的应用形态、App 和 Web 的关系,都主要侧重移动平台,而在发展时间更长的桌面平台上,已经几乎不存在这些问题:Web 平台和 Web 技术都是绝对的统治者

而且虽然移动互联网的市场规模远远超过桌面互联网时代,但桌面平台上的应用开发需求不但没有衰弱,反而也大幅增加了

在大陆,对这些需求有一个独特的称呼,叫做『中台应用』,这个词其实一定程度上能体现这种需求增加的本质:就是我们开始把面向消费者用户的产品背后的各个方面的基础能力,做成更通用的服务提供出来复用,并且通过桌面端的应用提供用户界面

幻灯片上是我随便搜的一张阿里的中台架构图,在字节跳动内部同样有大量中台应用项目,其实比起『App 工厂』,字节跳动更像是『超级 App 工厂 + 工具 App 工厂 + Web 工厂 + SaaS 工厂 + 中台应用工厂』

桌面应用需求的稳定和增加,还有一个原因是:我们在生活、工作和创造活动中使用的生产力应用,需要效率更高、更沉浸式的用户界面,所以需要类似桌面电脑、平板这样的平台

幻灯片上就是字节跳动开发的一站式工作平台『飞书』,它的移动 App 非常好用,但日常工作中我们使用更多的是桌面 App,这个 App 是基于 Electron 用 JS 开发

这种对沉浸式用户界面的需求,不会因为移动设备的流行而减弱,而且如果这种 UI 足够强大,它会不但适合工作,也适合社交和娱乐

今年 Facebook 发布了 Horizon,是一个 VR 社交应用,能让我们看到应用形态的一些新的可能性

但这种类似《黑客帝国》的产品,也容易引发不信任,很多人担心由 Facebook 这样的科技巨头控制的产品,越是包罗万象无处不在,越是能替代真实世界,就越容易获取个人隐私,会强迫用户看到更多广告,等等

最后来看一下开发工具有什么发展,这个领域在近几年其实已经发展成一个热门投资领域,涌现出很多基于开源项目、Web App 或云服务的初创公司,我想通过几个典型的融资事件来体现这种发展

去年 5 月,Prisma 获得种子轮 450 万美元的投资,Prisma 能为各种数据库自动生成 GraphQL API Gateway,让应用开发者可以直接在客户端或者 BFF 中编写业务逻辑,不需要依赖专业后端开发者提供围绕数据层的微服务

接下来 10 月,Netlify 融到 B 轮 3000万美元,Netlify 已经发展成国际上最主流的静态 Web 部署平台,既提供便捷、Serverless 的开发者体验,也为用户提供最快的访问速度

同样在 10 月,Replit 获得种子轮 450 万美元的投资,这是一个在线开发环境,为 60 多种语言或框架提供 WebIDE、终端甚至在线开发原生图形界面的功能,开发者可以不用在本地机器上安装这些开发环境和调试工具

再看今年 7 月,同样提供在线开发环境的 CodeSandbox 获得种子轮 240 万美元的投资,这个平台只支持 JS 和 Web 开发,但是提供了更好的框架集成,现代 Web 开发者可以打开浏览器就直接编写基于框架和编译工具的代码,立刻看到效果,不用搭建和配置环境

同样在 7 月,Glitch 也获得 A 轮 3000 万美元的投资,Glitch 也是一个专注于 JS 和 Web 开发的在线开发环境,致力于降低现代 web 开发的门槛,让写现代 Web 像以前写 HTML、CSS 一样方便直观

到了 9 月,Gatsby 获得 A 轮 1500 万美元的投资,Gatsby 已经发展成目前国际上最主流的建站解决方案,对传统的基于 CMS 的解决方案比如 Wordpress 造成严重威胁

所以 Wordpress 今年也做了巨大的革新

传统 CMS 在衰弱,Headless CMS 却越来越流行,这个月提供 Headless CMS 服务的 Strapi 刚刚获得种子轮 400 万美元的投资

我们刚才看了很多现状,包括三个重大问题、应用形态的发展、开发工具的发展,这些现状既是进步,给我们带来很多能力,解决很多问题,同时也提出了很多新问题

目前涌现的几个趋势中已经包含这些问题的解决办法,这些趋势都已经在发展中,是正在发生的未来

一个趋势是『内容开发』和『应用开发』之间的融合

前面提到过『前端开发』发生了『大分裂』,这种分裂的根源之一是:

『前端开发』原本是在传统 Web 开发中,为偏重『内容』的部分写代码,这些『内容』是后端 Web 应用的『输出物』,因为主要业务逻辑在后端,所以原始的 HTML、CSS 和少量 JS 就能满足需求,要考虑的问题也围绕『内容』,比如可访问性等等

而在现代 Web 开发中,『前端开发者』是负责写应用的人,要考虑整个 GUI 软件完整生命周期中所有问题,而且由于这些应用已经是客户端应用,不可能再向其他地方输出『内容』,需要在自己内部展现『内容』,所以『前端开发者』也仍然要负责『内容』的视觉、交互、可访问性等问题

『大分裂』的本质是:把『前端开发者』这个分工,照搬到『现代 Web 开发』中,导致这个分工需要同时负责『应用』和『内容』两方面的事情,而事实上,多数人只会擅长和偏好其中一种,要么成为严肃的『软件开发工程师(SDE)』,要么成为用户体验和内容方面的专家

身为设计师和前端开发者的 Brad Frost 提出一种方法,在设计和开发这两个分工之间,增加第三个分工,叫做『前端设计(Frontend Design)』

表面上看,这个方法好像是要倒退回过去,在设计师和以服务器端开发为主的工程师之间,增加一个『前端开发』的分工,但换个角度来看,这种方法其实反映了『大分裂』的本质,就是被照搬到『现代 Web 开发』中的『前端开发』,根本就不是一个工种,而是两个工种

近几年的技术发展和生态建设,都是围绕如何让『应用开发者』做好自己的工作,取得了很大进步,现在的问题是,不能把这套东西照搬给其他工种,同时也不能只是维持他们过时的工作方式,需要提供新工具,让他们融入到『现代 Web 开发』的新范式中

Brad Frost 指出其中一个工具就是现在发展相对成熟的『UI 组件』,我们可以对组件做分层,把偏视觉、交互、内容、可访问性的这一层交给其他分工去产出,成为『可消费的 UI 组件』,这种组件可以成为『大分裂』中的桥梁

现代 Web 开发的发展,也在为这种新分工、新工具提供支持,前面提到的 Gatsby 之所以能成为主流解决方案,拿到大笔融资,很大程度上是因为它体现了 Content Mesh 这个趋势,可以翻译成『内容网格化』或『网状内容』

在传统 Web 开发喜欢采用的 CMS 架构中,数据、内容编辑、内容展现、业务逻辑、托管交付,都是混在一起的,必须用一套方法来提供,就好像用了 Wordpress,技术栈和部署托管都避不开 php,客户端部分也必须基于 Wordpress 主题

而在现代 Web 开发里,每个不同的部分都有各自最合适的解决方案,其中很多都有可复用的、更专业的服务,类似大陆常说的『中台』的概念,只不过这些『中台』不仅限于在大型企业内部复用,而是面向公开市场提供服务

比如表单问卷需求可以用 BaaS 服务 TypeForm 解决,用户授权鉴权可以用 BaaS 服务 Auth0,图文内容可以直接用 Markdown,支付可以用 Stripe,所以现代 Web 开发中的应用,不是一套技术解决方案,是多种混搭在一起的,在每个问题上,都应该能用最合适的方案和工具

虽然是混搭,但从架构上看,发展趋势是简化成两大块:

一块是现代 Web 应用本体

一块是 Serverless 平台,其中又可以简化为两大块:『交付云』和『后端云』

『交付云』支持静态 Web 部署,支持边缘计算,也可以支持 SSR 部署,SPR 部署等

『后端云』由 BaaS + FaaS 组成,既可以取代现代 Web 项目中的 BFF 部分,简化开发,也可以直接取代很多微服务的开发需求,而 GraphQL API 可以让它的能力和适用面大幅增强

在字节跳动,前端工程师的服务器端开发工作已经越来越多的在『后端云』上完成,不再需要自己开发部署运维 Node.js 服务

现代 Web 应用的本体中,核心是『应用架构』,假如一个 Web 项目只有 React 组件代码,它就只是一个 UI 和内容展现,正是因为加上了『应用架构』,才从 UI 和内容变成了 GUI 软件应用,后面还会提到『应用架构』里应该有哪些东西

最后我们再看 UI 组件这个部分,经过这些抽象之后,相当大的一部分 UI 组件都可以成为前面说的『消费型 UI 组件』,可以由外部提供

要让其他分工可以更高效的独立提供这些 UI 组件,需要进一步的工具支持

直接让这些同学使用依赖管理、编译工具、CLI 工具等面向软件开发工程师的工具链,是门槛很高、很痛苦的,所以我们需要从图上的『语言和框架』这个点之后开始提供工具

首先是 CASE 工具(Computer Aided Software Engineering,也就是『计算机辅助软件工程』),把工程和软件设计中的最佳实践、数据可视化和常用操作,封装到图形界面、免安装的工具里,屏蔽底层技术细节的复杂性

更进一步是提供低代码工具(Low-code),让有些工作不需要写代码也能完成

从这里开始,就已经进入了前面说过的『设计工具』的范畴,开始同时解决『大困境』问题,我们这里提供的不再是传统上基于图像的设计工具,不再是只能设计出『效仿』最终产品的输出物,不再需要『在设计和开发之间架设桥梁』,而是把代码作为『唯一权威来源』,让各个分工都围绕着代码来协作

最理想的解决方案是提供无代码工具(No-code),即使不懂技术、写不了任何代码,也能融入到工作流中

在这个方面,游戏开发作为一种垂直领域的应用软件开发,比通用的应用软件开发要领先数年,游戏设计师可以用『关卡编辑器』这样的工具,低代码或无代码的产出最终产品的代码,跟工程师写的代码无缝集成,所有分工都围绕着同一套最终产品的代码来协作

现代 Web 开发要实现像游戏开发领域这样高效、顺畅的工作流,趋势上一定会发展出像游戏引擎一样的工具套件,形成新的分工模式,所有分工都围绕着同一套工具、同一套代码来协作

我在字节跳动负责的 Web Dev Engine 部门,就在专门推进这方面的工作,套件中的 Meta-framework 部分,跟我们要看的第二个趋势有关

第二个趋势解决的是『开发者体验』(DX)和『用户体验』(UX)之间关系的问题

大家都很熟悉『库』的概念,JS 拥有所有语言中最庞大最繁荣的 npm 生态,有海量的『库』可以在我们自己写的代码里调用,这些库通常会专注于单一目的,提供强大灵活的 API,在实现目的的同时,满足需求和场景的各种变化

这些库提供的是单块积木,可以自由组装成我们想要的样子

而『框架』是另一种类型的基础生态,可以说一个现代 web 应用的框架,就是应用本身,框架不是积木,而是很多底层积木组装出来的整个拼图,只是需要在特定位置或环节,插入我们自己写的代码或提供配置,满足特定需求

无论库还是框架,如果要把 DX 和 UX 同时做到最优,组装、配置、开发工作都会变得很繁琐低效,大量注意力不能放在真正的业务需求上,而是被库和框架的底层技术细节占用,由于成本高,相关的基础建设也很容易在技术选型和排优先级的时候被忽略或推迟

这是 JS 生态在主流问题域里的积木稳定之后,面临的一个主要问题,Meta-framework(元框架),也就是『框架的框架』,正是为此而生

接下来我们看几个元框架功能上的趋势

第一个功能是支持『混合语言开发』

近年来非常明显的趋势是,TypeScript 已经成为主流语言,TypeScript 虽然解决了很多重要问题,但现代 web 开发领域中还有很多问题,解决方案都在 TypeScript 社区之外,由于以前 TypeScript 社区跟 JS 社区是有些割裂的,所以有人形容用 TypeScript 做项目是要交 『TypeScript 税』的,比如无法使用 JS 生态中的某些方案,总体来算,ROI 甚至可能是负的

TypeScript 官方自己也能认识到这个问题,开始积极跟 JS 社区融合,比如废弃 TSLint 项目,跟 ESLint 合并,为 Babel 开发语法插件支持 TypeScript 编译

我们看近两年来的使用数据,Babel 的 TypeScript 插件增长速度基本跟 TypeScript 本身一样,ESLint 的 TypeScript 解析器即将超过 TSLint,而 Babel 不但使用量比 TypeScript 大,增长速度甚至更快

所以在现代 Web 开发的项目中,JS 和 TS 正在融合过程中,不可能完全排除其中一种,甚至很多时候需要混用

混合语言开发的需求的增长,同时受到了来自 DX 和 UX 两个方向的驱动,比如:

需要考虑到 Node.js 特有的一些语言特性(DX 驱动)

需要用 Rust 开发 CPU 敏感的模块生成 WebAssembly 集成到项目中(UX 驱动)

需要在局部模块引入 Reason/OCaml 的函数式编程能力(DX 驱动)

等等

元框架可以隐藏混合语言开发的复杂性,推动最佳实践的普及

第二个功能是 CSS 开发解决方案

CSS 开发的发展趋势就像图上时间轴中列举的这样,是从『面向文档』向『面向组件』发展,『面向组件的 CSS』是一种同时改进 DX 和 UX 的模式,在给 CSS 带来完善工程能力的同时,能生成尽可能高效的 CSS 静态文件

CSS Modules、styled-components、Functional CSS,这三个方案表面上看差别很大,一个是预编译 CSS 文件,一个是 CSS in JS,一个是全局的 utility class,但本质上这三个方案都是在实现『面向组件的 CSS』

如果我们把 Functional CSS 提供的 utility class 看成组件的名称和属性,添加一个 class name 就像把组件上的同名属性设成 true,那么它跟 styled-components 没有本质区别,在真实项目中,混用这两种方案的收益最大

从今年的 CSS 普查报告上,也能看到 Functional CSS 的流行

第三个功能是对 monorepo 的支持

monorepo 这种模式目前还主要用在库的开发中,比如 Babel 这样有大量子项目的仓库,但其实现代 Web 开发中的多数项目,都能从中受益

比如幻灯片上是我们团队的仓库,同一个产品的多个组成部分,比如多个 SPA 应用、多页网站、落地页和活动页,可以在一个仓库里共享工程环境,方便的复用代码,而 BFF 的开发也可以在同一个仓库,跟客户端共用一些代码

第四个功能是对微前端的支持,微前端正好是一种兼顾 DX 和 UX 的设计模式:

在用户体验这边,可以做到完全无感知无差别,仍然是一个完整的 SPA 应用

第一屏无论包含多少微前端,都可以通过 SSR/SPR 和边缘计算提供最好的加载速度和体验

而第一屏不包含的微前端,可以按需加载,不会影响跟自己不相关的其他微前端

不同微前端之间可能彼此独立,也可能有数据交互,需要打通应用状态

以上用户体验虽然都能够实现,但如果没有元框架的支持,成本会比较高,容易顾此失彼,解决方案之间的不一致也会影响效果

在开发者体验这边,恰好可以为前面说的「垂直分工模式」提供支持,不是由同一个项目同一批前端开发者来负责所有业务、所有不同类型需求的前端部分,而是每个业务、每个垂直领域有自己独立的团队(或开发者)负责,开发环境、开发过程、部署流程等完全彼此独立自己掌控,但最终交付给用户的时候仍然是一个完整单一体验的应用

第五个功能就是前面说过的「应用架构」

初级的现代 Web 项目只是在视图层之外增加了应用状态管理,比如 React 社区中主流的 Redux

但 Redux 实际上是一种「底层 API」,主要提供「机制」,并不提供「架构」的设计和实现,「架构」本身是一种顶层抽象,而 Redux 恰好是缺乏抽象的

近年社区里流行的「Rethinking Redux」、「Replacing Redux」的根源之一其实也是这个问题

元框架无论是否借助上游项目,都要负责提供顶层抽象,比如 Component、 Model、Container 铁三角加上 App 入口,既为开发者提供开箱即用的应用架构,反过来也掌握了关于应用项目代码的「架构知识」,能从抽象角度理解代码,进一步提供有利于 UX 和 DX 的能力

元框架还可以从更高的项目视角来看待「应用架构」,结合框架其他部分提供更强能力,比如把项目入口的运行和部署方式、微前端模式和基础设施跟应用架构打通

第六个功能可以称作「智能助手」

软件开发方式已经经历了「基于文本」和「基于结构」两个发展阶段,在第一阶段,开发工具能理解和处理的是文件、行和文本流,第二阶段,开发工具能更多的把代码理解为结构化的信息

当前正在发展中的「第三阶段」是「基于智能」,开发工具能更智能的理解代码、查看代码和生成代码,最终会趋向于一个「智能助手」,我们做开发的过程越来越不再是直接用源代码跟机器打交道,而是跟「智能助手」沟通,获得最好的 DX,智能助手再去跟机器打交道,实现最好的 UX

这种范式转变已经在发生,如果在开发流程中引入了 Prettier,你手写的代码就不再是源代码本身,而是用来跟 Prettier 沟通的代码,最终保存在硬盘上,提交到仓库的源代码,是 Prettier 重新「写」出来的

ESLint 社区也把 autofix 作为最重要的发展方向来推进,能自动修复的规则已经越来越多,但是跟 Prettier 相比还是有范式上的差别:

幻灯片上有一个例子,如果设置了 80 字符的最大行宽,ESLint 和 Prettier 都能修改代码自动换行,但经过 ESLint 自动修复后,代码还是可以有多种写法,只有不触发 ESLint 规则报错就行,而 Prettier 处理后的代码只可能有一种写法,因为代码是它「写」的

所以 Prettier 以及「智能助手」是一种「有偏见」的范式,对于 Prettier 怎样「写」代码,开发者的话语权很少(能配置的地方很少),如果你先凭空写好一套代码规范,再用 Prettier 来实现,是不可能的。但正是这种「偏见」才能给 DX 和 UX 同时带来最大化的收益

「智能助手」的发展需要一个过程,在这个过程中,最佳实践是把新旧范式整合在一起使用,随着相关工具的进步,逐步在越来越多的地方把旧范式切换成新范式

比如使用 Prettier 的最佳实践就是把它作为规则插件整合在 ESLint 中,跟 ESLint 的 autofix 一起执行,对于所有 Prettier 能决定怎么写的代码问题,相关的 ESLint 规则都失去意义,要关掉。随着「智能助手」的能力越来越强,需要关掉的 ESLint 规则也越来越多,直到完全不需要 Lint

「智能助手」的使用应该是基于即时反馈的,因此这种范式最佳的使用场景是在开发环节,而不是在编译构建、提交仓库、CI/CD 等环节

幻灯片左侧是 VSCode 相关配置的最佳实践,每次保存代码都是跟智能助手的一次「沟通」,立刻看到它生成的代码,在这些代码基础上继续再做「沟通」,这样的过程是符合直觉的,不会带来「惊喜」,也不会有失控感

幻灯片右侧是另一个最佳实践,可以称作「全量规则集」:

传统上使用 ESLint 的方法是「白名单」模式,我有哪些代码规范上的需求,就开启和配置哪条规则,

而「智能助手」范式是「黑名单」模式,默认开启所有规则(包括ESLint 核心和所有主流插件),对于没有偏好或根本还没听说过的规则,都使用主流推荐配置,只把自己了解且明确不想用的规则关掉

这种「全量规则集」跟 Prettier 一样可以提供最大化的「约束」和「偏见」,给 DX 和 UX 带来最大化的收益

第七个功能是对设计系统的支持

设计系统不止要提供「组件库」,还需要提供组件之间的关系(包括组件的用法,设计规范等等)

Atomic Design 的概念来说,不可拆分的「原子组件」、以及由「原子组件」组合成的「分子组件」,共同构成「组件库」,但整套系统还包含了建立在组件库之上、包含组件之间关系的「有机体」

在设计系统成熟的情况下,前面说过的「可消费 UI 组件」主要都会是「有机体」

元框架需要为「有机体」的开发和使用提供支持

近年来,设计系统的设计和实现中开始流行 Design Token 的概念,就是发现「原子组件」并不是不可拆分,可以由作为更小单位的一系列变量取值来组成,换一套不同的取值,设计系统就能支持不同的视觉风格和品牌形象,既降低开发成本,也提升用户体验

第三个趋势是 Web 形态的一个发展方向

今天的互联网技术是 80 年代设计的,这套技术非常简单成功,但因为缺少一些重要元素,导致今天的互联网面临很多难以解决的问题

其中一个重要缺失就是没有「持有状态」和「转移状态」的原生机制,导致状态只能存储在少数中心节点,由这些节点在黑箱中处理状态转移

于是互联网越来越「多中心化」,从开放互联的状态,收敛成少数几个中心,由不同的科技巨头控制,彼此难以联通或直接敌对,前面提到的对科技巨头产品的不信任也由此而来

用户对自己的个人数据(状态的一种)缺乏掌控,无法参与由数据产生的越来越多财富的分配,缺少激励或补偿,减少了在生活中使用互联网产品的积极性(大陆很多面向下沉市场的产品会人为提供游戏化的激励或补偿,因此能飞速增长),同时因为对黑箱缺乏信任,也进一步降低了积极性,或人为增加监管和限制。

这种扭曲最终反噬互联网产品和科技公司,让他们难以为用户创造价值,也就是说,这个话题看上去很大,但是跟现代 Web 开发者是有关系的

所以 Web 形态的发展,有很大动力引入像智能合约和区块链这样的架构和范式上的转变

图中是新范式的一个例子,现代 Web 应用的后端不再是中心化的服务器端 API,而是部署和运行在区块链上的智能合约 API,状态存储在去中心化基础设施(区块链)上,由去中心化程序(智能合约)负责状态转移,这个现代 Web 应用也就成为了去中心化应用(DApp)

对现代 Web 开发来说,这种范式转变不但不会颠覆当前的发展和积累,反而会促进原有的趋势更快发展

比如基于智能合约的应用架构就是一种 Serverless 架构

但是产品的形态和机制会有很大改变

最后讲一个案例

开头部分的幻灯片提到过,我做过的产品里,最喜欢是 2011 年在豆瓣做的阿尔法城 2.0,这是一个让线上的兴趣社群像城市空间一样有地理关系,根据用户行为自然生长的新形态社区产品,有 2D Metaverse(虚拟世界)的形态

向 Immersive Metaverse (3D 沉浸式虚拟世界)发展也不难

这个产品的开发只持续了一年,团队就解散了,运行四年后下线

失败的原因之一是:用户方想要的,企业和产品方想要的,两者之间有距离。就好像你想给用户 A,结果只做到了 B,而 B 的用户在使用过程中真正想要的是 C,但你只想要 A,所以把 B 关了

这里面有一个严重问题是:用户决定不了任何事情

用户像开发团队一样,在产品中投入了时间、注意力、技能、情感,创造了价值(UGC),但即使在这样一个主打「自然生长」的产品里,用户决定不了自己贡献的数据何去何从,决定不了自己喜欢的产品功能的命运,决定不了产品的走向和生死

正在演化中的新一代 Web 技术和市场环境,已经提供了比阿尔法城那个年代更好的条件和手段来解决这些问题

我相信在 Web 上创造出新世界的那一天距离现在并不遥远

如果你对以上问题有兴趣,想直接穿越到它们发展完善的那一天,或是想体验亲手把它们发展完善的过程,甚至感受到使命感,欢迎加入字节跳动的 Web Dev Engine 部门一起努力,目前我们的 8 个虚拟团队由来自北京、上海、深圳、厦门的同学组成,而字节跳动在大陆主要城市和全球很多地方都有研发中心,总有一个地方适合你加入我们 XD,可以扫二维码提交简历或直接联系我

编辑于 2019-10-27

文章被以下专栏收录