2

本系列博文从 Shadow Widget 作者的视角,解释该框架的设计要点,既作为用户手册的补充,也从更本质角度帮助大家理解 Shadow Widget 为什么这样设计,相关概念是怎么提出的,正确的使用姿势等。

救赎

1. 前言

"非正经入门" 是相对 "正经入门" 而言的。

正经入门 Shadow Widget 的路数是:按照 Shadow Widget 技术栈的依赖顺序,依次学习各个手册,比如 React 处于最底层,到它的官方网站找材料学习,React 之上是 shadow-widget 与 shadow-server,到 github.com/rewgt 找到这两个 repository,克隆到本地,按顺序学习各 repo 附带用户手册,然后其上还有 shadow-book、shadow-slide 等 repo,若用到了,就学习相应的用户手册。"正经入门" 的学习方式是学院派的,严谨、完整、成体系,对于大部分用户来说是首选。

但终归有些老司机是不正经的,正襟危坐弄那么多前戏会很不耐烦,好吧,这几篇博客就是为他们准备的,我尝试直击人心讲要点,不求全面,也不要求从未接触 Shadow Widget 的童鞋一下就看懂,解释过程可能挂一漏万,见谅先。不过不要紧,正式学习仍需回到 "正经入门" 的方式。

要求读者对 React 开发技术已有深入了解,否则,嗯,还请回到 "正经入门" 的学习方式吧,这几篇博客用作技术回顾也是不错的,能让大家对 Shadow Widget 体系的本质性原理认识更深入些。

2. 快速入门建议

1) 先学会用拼文写文档

注册一个 github 账号,把 rewgt/blogs 库 fork 到自己名下,然后用这个库写自己的博客,参见 这份介绍

Shadow Widget 界面设计严重依赖两样东西,一是使用 markdown 语法,二是所见即所得的 UI 可视化设计器。这两项也是写文档随时用到的,比如撰写演示胶片时,胶片页编辑器就是 Shadow Widget 可视化设计器。会用拼文写文章,相当于 Shadow Widget 开发已入门三分之一了。

2) 系统化学习《Shadow Widget 用户手册》

包括理论篇、基础篇、进阶篇、API手册、可视化设计使用手册。

多数软件的用户手册仍是最佳入门教材,尽管网上常有人编写《XX系统最佳入门》之类的教材,让人误以为是捷径,其实,多数情况下,都没有阅读原配用户手册学得快。

Shadow Widget 编程体系具有内敛特质,入门时学习工作量较大,入门后,在 Shadow Widget 之上的众多组件(或库)都是扩展插件,规格一致,学起来很容易。另外,借助可视化设计的特点,记忆负担轻,基本上通过拖入一个样板来创建构件,选中构件后配置它的属性,遇到不清楚的 API,再查一下在线帮助,很方便的。

3. React 三宗罪

事先申明,React 是一个优秀框架,我不黑 React。

所提三宗罪基于世俗观点,人们常将 React、Angular、Vue 三者并列比较,其实 React 只是虚拟 DOM 层面的库,在 React 之上叠加若干工具,比如使用 immutable 数据、形成 FRP 处理框架、叠加路由机制等,之后,React 才与 Angular、Vue 是对等的。将 DOM 库拔高与别人比较,显然对 React 不公。但现状如此,谁让 React 确立一种编程模式呢,其实将这三者并列比较的人,心里也很清楚,他比较的是三种生态链,而非只是三个工具。

因为 React 确立一种函数式的,单向数据驱动的,JSX 与 JS 代码混写的编程模式,既有它的先进性,也必然引入一些让人垢病的因素,下文 "三宗罪" 所列就是典型的负面因素,也是当前 React 生态圈尚未有效解决的焦点问题。当然,shadow-widget 出世后,这些不利影响也基本消除了。所以,React 三宗罪是 "React + 其它" 的三宗罪,不是 "React + shadow-widget" 的三宗罪。

3.1 三宗罪之一:长工具链

学习 React 要面临超长工具链,这是不利消息,好消息是,这套工具链经过数年磨炼,现在基本稳定下来了(坑还是不少,前人有总结,你不把它当坑就行 emoji)。关于超长工具链,请参考我的上一篇博客 《Shadow Widget框架概略介绍》,React 工具链尚在春秋战国,过于发散、杂乱、低效,而且,在严谨普适的方法论与直观易用之间,还没找到最佳平衡方式

当年 Brendan Eich 创造 javascript,仅为简陋的网页增加一点简单编程手段,现在的 JS 所处生态环境,远非早年样子,即便五年前,网页编程还都是很简单,一个 jQuery 解决大半问题。事实上,这种简易的形态反倒与网页主流状态相适配,多数网页只是展示信息,加点小量编程就够用。现在问题是,轻量编程与重量编程之间没有界限,有时刚开始是轻量的,一边维护一边追加功能就慢慢变重了,有时自己负责部分是轻量级的,但与他人对接,别人是重量级开发,不得已被同化成重量级应用。

我的意思是,一个好的前端框架,应该同时适应轻量级与重量级开发,两者之间过渡是平滑进行的。在草创阶段,不管面对多复杂的系统,都应是轻量级的,叠加功能,应该只是容量递增,而非架构重建。目前主流的 "React + redux + react-router" 用法,加上无法省略的 Babel 编译工具,一入手就是重量级开发。所以,现在许多人面对轻量级网页开发,宁可啥框架都不要,用回老旧的 jQuery。

Shadow Widget 建立一个插件式框架,"开发新构件并封装成样板" 是一件工作,"使用现成构件组装 APP" 是另一件工作,两件工作截然分开。对于后者,可避开 Babel 翻译,用 ES5 语法能很好做开发了。此外,Shadow Widget 内置与 reflux/redux 对等的单向数据流机制,与 react-router 等价的也有内置实现,其它的,如 immutable 数据、ajax 调用等都内置支持了。总之,"React + shadow-widget" 是完整的前端框架,与 Angular、Vue 功能对等。

在 Shadow Widget 之上扩展的 PINP Blog,更是将写文章与编程拉通,实践 "写作即编程" 的理念,从轻量开发过渡到重量级开发,是很自然的过程。

3.2 三宗罪之二:JSX浆糊

JSX 看起来像 html,能直接描述界面设计,我们拿 React 官网上一段代码来举例:

function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}

上面 formatName() 也是用户定义的一个函数,函数调用、变量引用都能杂凑在 JSX 中使用。这么做好处是编程灵活,坏处是破坏了界面与底层的解耦,使用 JSX 获得便利同时,也绑架它的上下文实现,因为这个 JSX 的本质是一段代码,在特定上下文才有效(相关变量与函数才可用)。我们称之为 "JSX浆糊",使用的 JSX 与特定编程片断粘糊在一起了。

"JSX浆糊" 直接的负面影响是,界面设计与其它部分没有分离,所以,尽管 React 生态圈中的轮子如此丰富,但鲜见以 "所见即所得" 支持可视化设计的解决方案,不得不说 "JSX浆糊" 是祸首。

Shadow Widget 通过一系列手段解决 "界面设计" 与底层分离的问题,不过,它的分离机制在 React 基础上叠加,React 原机制并未破坏,如果想用 JSX,仍正常可用。此处理方式反映了我们的 "实效主义" 策略,一方面认同 React 那种函数式、单向数据流的处理机制,另一方面,也正视函数式编程与可视化开发天然有冲突,面向对象编程与可视化开发更亲近些。

不追求纯正的函数式开发,不强调纯函数组件,什么东西最有效,能解决问题就选它。本系列文章后面还会解释,函数式开发的思维方式既有优势也有劣势,尤其将 FRP(Functional Reactive Programming,函数响应式编程)严格应用到现实项目,必然遭遇反人性困局。编程的世界里没有纯粹的东西,因为人性并不纯粹,过份追求 "纯正" 会让事情走向反面。

3.3 三宗罪之三:分层解耦

软件开发中有两类分层,一是软件功能的分层,二是人员的分层。当前端开发变复杂后,这两类分层的需求变得更强烈,尤其针对简单网页的开发,你不能要求所有开发人员都是专家,但 React 生态链的现状是,能用 React 正式开发产品时,你已经是准专家了,在有产出之前,你要熟悉一堆工具、一堆规则、一堆语法,要踩不少坑。

React or Vue

网上有人对比 React 与 Vue,说用 Vue 是先爽后痛,用 React 则先痛后爽,还有人补充说,用 React 一直痛,没有爽。这些说法大致准确,React 体系遵循严格的函数式编程风格,从它选这条路的第一天开始,就意味着要 "先痛",至于后来 "爽不爽" 还得看它的修为,想像一下用 LISP 开发 GUI 程序是怎样一种感受吧?函数式风格与指令式存在本质性差异,推演下来,反映到 React 与 Vue 上必是这种效果。所以,函数式是 React 体系的原罪,shadow-widget 是为 React 赎罪来的。

用 Vue 爽后还得痛,反映了这个领域做开发本来就这么复杂,入手门槛虽降,但晋升为专家的路上,该受的苦,该踩的坑一件不落。不过,Vue 也是优秀的前端框架,它与 React 对比,基本在对比指令式与函数式的优劣,作为工具本身,两个都很优秀,可指责的不多。平心而论,若从中长期收益考虑,在 React 系统已引入 MVVM 框架的前提下,选择 React 更好些,它出彩的地方是在虚拟 DOM 与 FRP 编程思维。不过,怎么说呢?vuex 也引入虚拟 DOM、store、action 机制,它们越长越像了。

上述结论要预设一个前提:在 React 引入 MVVM 结构,这很重要,Shadow Widget 已经干了这事。React 官方宣称 React 符合 MVC 分层,并未宣称它是 MVVM,其工具链上主流工具延续了这一定位,事实上,受限于 "JSX浆糊" 等因素,想把它改造成 MVVM 还是要动一番手术的,不像 Vue 与 Angular,与 MVVM 天然走得近。

我扼要概括一下 Shadow Widget 是如何改造的?

首先确定目标,让 React 适合于可视化开发及人员分层,人员分层是将开发人员分两拨,一拨低要求,实习生就能做,主要使用现成构件样板组装 APP,其门槛只比用 jQuery 做开发稍高一点,另一拨高要求,能开发新构件并封装成样板,什么都得学。

其次,设计转义标签、json-x 描述、投影定义等机制,让界面与底层分离,实现 MVVM 框架,相关细节请看《Shadow Widget 用户手册》。最后,引入双源属性、可计算属性等概念,把 React 的函数式编程往指令式方向上拉回一点,或者更准确一点说,在界面设计,即 "V" 层,采用指令式风格,而 "VM" 与 "M" 层仍沿用原先的函数式风格。

4. Shadow Widget 渊源

Shadow Widget 由 PINP.ME 团队研发,PINP.ME 一直专注于提供以 HTML5 技术撰写文档的工具,包括类似 WORD 的博客文档与类似 PPT 的演示胶片。最早发布的 PINP 版本距今已有四年,早期的 PINP 采用 Ractive 框架,后来全盘重构,改用 React,就是大家现在看到的 PINP Blog 产品

PINP logo
    (PINP 的 logo)

 

PINP 改版最大变化是,层次划分更清晰、开发方法更先进,推出的版本也更稳定了。另外,在底层把 shadow-widget、shadow-slide 专门独立出来,让 shadow-widget 自成一个体系,不只 PINP 工具能用,也尝试让 "React + shadow-widget" 成为一个简单易用的前端框架。

(本文完)

本专栏历史文章:

  1. 《介绍一项让 React 可以与 Vue 抗衡的技术》

程序强
128 声望31 粉丝

React 死忠分子。。。。程序哪家强?过来看这里。