Web Component 和类 React、Angular、Vue 组件化技术谁会成为未来?

类比现在 HTML5 和 RN、Weex 技术体系,标准的 HTML5 显然是无线端的未来(只不过时间未知),特别是 PWA 技术等技术的兴起,会进一步推进,起码有点希望。 反观 Web Component 是 W3C 专门为组件化创建的标准,包括一些 Shadow DOM 等特性彻底的、从浏览器的层面解决掉一些作用域的问题(例如全局覆盖的 CSS)。而且也不需要构建、编译,直接跑在浏览器上。但是因为众多坑导致一直难以流行。有一些大公司(例如 Google)也研发…
关注者
687
被浏览
29592

12 个回答

一点补充内容:

Web 「相关」规范(这里包括 Web API、ECMAScript 语言和常用的 Protocol 等)设计中一般有一些基本的共识:

  • 每一个 Web API 只做一件事;
  • 同一个功能不会有两个类似的 API 来做(除非是用新的 API 来取代过于落后的 API);
  • 保持 ECMAScript 的平台无关性;
  • 保持 Web API(IDL 及语义)不强依赖于 ECMAScript;

比如我们能够发现:

  • Web Components 不是一个规范,里面的每个规范都是独立的,并且其功能是有意义的。例如我们可以只用 Custom Elements 来扩展 HTML 语义;使用 Shadow DOM 来隔离 CSS;使用 Template Tag 来实现动态 DOM 生成;使用 HTML Imports 来引入外部内容等。
  • Web 的本质是一个平台,所有 API 都是平台的底层 API,首要目的也不是为了方便使用。除了类似于 XHR 或者 document.getElementByXXX 这样过于繁琐的 API 已经出现了替代品之外,并不会有出一个 Fetch 规范、一个 Request 规范、一个 SuperAgent 规范来满足不同用户的喜好。所有不影响功能实现的需求都应当自己通过封装来解决。
  • ECMAScript 语言本身不会出现依赖于 DOM API 的内容。
  • 虽然 ECMAScript 目前是事实上被钦定的 Web 开发语言,但是所有 Web API 规范中都是用的语言无关的 Web IDL 来定义的,几乎不会出现(显式)依赖于 ECMAScript 的情况。

所以为了满足题主实现类 React 框架的要求,可能的方式是:

  • ECMAScript 中增加 XML Literal 语法的支持,类似于 Scala 和 VB,增加一坨 Built-in 的类。
  • 复用现有的 Custom Elements API 作为组件基础,其本身已经提供了良好的生命周期特性,没有特殊的必要不可能重新引入一个类似的又没什么创新的同类 API。
  • DOM API 中增加一个 Virtual DOM API 子集,内置 Diff 功能,还要提供一套复杂的配置机制。

这样做出来的效果也不会比目前好多少。

根本的问题在于,框架的职责在于提供一整套的解决方案,而平台 API 的设计要求是绝不能提供一整套的解决方案(即保证零耦合、正交),这是无法调和的基本矛盾所在。


---

先说观点:Web Components 一定成不了气候,但会继续演进下去;Angular、React、Vue 谁也不会成为 Web 标准;JSX 永远不可能得到原生支持。


现在 Web 前端的痛点并不在于「最新的」浏览器原生支持的特性不够,而是「需要兼容」的浏览器原生支持什么的问题。

Web 开发中,标准化的意义在于,

  1. 需求与实现的分离,例如某个类库需要使用 Promise,但不需要纠结具体用哪个 Promise 实现,应用所有者自行 Polyfill 出来即可,避免出现用到了多个库都分别自带了自己私有的 Promise 实现;
  2. 知识和工具的复用性,例如大家都学的是同一个 JavaScript 语言/Web API,文档和教程可以通用,避免每个人都去用自己的方言编译到 JavaScript;
  3. 给 Web 开发指明一个<del>正确</del>合理的发展方向;
  4. 给 Web 平台提供更多的功能。

为什么说 4 不是那么重要呢?因为 Web 的使用方式确定了实现的滞后性,(相关)标准必然会领先于现有实现(如果要进步的话)。绝大多数人所做的都是通用 Web 开发,而非面向最新浏览器开发。被「规范」原生实现的东西,并不等于产品中可以视为原生实现,即便使用 Web Components,该构建还得构建(利于 extends HTMLElement 用到了 ES2015 的 class),该带运行时还是得带运行时(除了 <template> tag,Custom Elements、Shadow DOM 和 HTML Imports 显然都需要对应 Polyfill)。

所以现实情况是,用「规范」定义的原生方案也需要 Compilation 和 Polyfill,用「第三方」的模拟方案也需要 Compilation 和 Polyfill,那么这时候该如何选择呢?为了 Web 规范的茁壮成长,大家为什么不都主动选择符合「规范」的方案呢?

不幸的是,「规范」永远都是<del>落后</del>保守的。不论是功能覆盖、API 设计还是可塑性。作为「规范」,这种取舍也是正确的。对于 Web 组件话方案而言,从 Angular、React 和 Vue 中任选一个,都能获得比「规范」所提供的方案更多的功能、更快的反馈周期和更高的自主性。所以,在同样需要 Compilation 和 Polyfill 的情况下,何乐而不为呢?

除了组件化之外,哪怕是 Fetch(Fetch API)这种可以算作及其先进的 Web API,也很容易看出这种弊端:虽然相比于 XHR 极大改善,但是本身功能仍然过于简洁,在复杂应用中仍然需要自行封装,随着封装力度的不断加大,性价比还不如直接使用第三方的 HTTP 类库。


所以回到框架的问题上,Angular、React 和 Vue 等 Web 框架(或者根据个人喜好叫类库、平台)等,都不可能成为 Web 规范,或者说,不成为 Web 规范才是它们的意义所在。

如果对于一个 Web 框架,新增一个 Feature 需要过两年才能使用,<del>提交一个 Bug 需要过两年才能修复</del>(不不不,对于 Web 规范而言,没有 Bug、只有 Feature,所谓的 BUG 只是特例而已,记住了就好,以后都会成为面试考点),这样的 Web 框架还有何意义?

不过,虽然本身成为 Web 标准没有意义,但是与 Web 标准共同发展仍然是一件好事。如果一个技术在 Web 框架中得到广泛应用,那么可能这个技术能够成为 Web 标准的一部分;反之,如果一个 Web 标准得到广泛支持,那么 Web 框架也能在一定程度上受益于这些标准。


然后对于 JSX,目前所谓的 JSX 规范(facebook/jsx)只涉及语法,不涉及任何语义部分。也就是说,目前根本没有规定对于一个 JSX 的扩展语法应该实现成什么样子。

React 会把它编译成 React.createElement(),Vue 会编译成 _h(),Inferno 会编译成 createVNodes()。于是问题来了,用哪个 JSX 的实现作为标准呢?不光是命名空间,内部的结构组织大家也都不一样。如果真要新增为 ECMAScript 的语言特性,那么肯定是不会使用一个第三方的 namespace 的,于是作为标准化的语言特性,又增加了一种叫做「标准」实现的实现。但是另一方面,一旦要把 JSX 列入到 ECMAScript 中,也就意味着目前所有基于其他 JSX 实现的代码全都会被 Break down。或者换句话说,就是因为大家本来都不打算让 JSX 成为 ECMAScript 的一部分,才会分别大力发展自己的私有实现。

结合前面的部分,就算实现了,并不影响你所需的构建步骤(对于通用 Web 应用而言),然后又与所有当前的代码不兼容,完全没有必要这样自找麻烦。


Web 开发永远会趋向于「在保证可实现性的基础上尽可能提高生产力」的开发方式,即便现在的 Web Components 真的被普遍实现了,大家也会继续追求新的扩展以及新的高层抽象。


总结:

  • Web 开发由于其存在方式,必然需要在「避免构建」和「提高生产力」之前作出选择;
  • Web 标准必将长期保持领先于「浏览器实现」,落后于「可行的最先进方案」的状态;
  • Web 框架/类库/平台的先进性可能需要其不被标准化才能持续保持;
  • JSX 没有一个统一的语义,且平台相关性过于显著,不太可能被吸收进 ECMAScript。

未来有两个含义,一个是“未来标准”,一个是“未来最具主宰地位的框架”。

要说未来标准,那肯定只有Web Component有希望,React/Angular/Vue因为其背后的开发者背景是绝对不会成为标准的。Web上的标准有一个缺点,就是制定标准的人不是开发Web应用的人,所以总是要比Web应用的需求慢一拍,一些需要被React/Angular/Vue满足了,标准才刚起步,所以,就算Web Component成为“未来标准”,也很可能没人鸟他。

当然,不能说Web Component没有前途,至少Google除了Angular之外也在推进Web Component,Youtube就采用的是适应Web Component的Polymer。

至于“未来最具主宰地位的框架”,我觉得还是三足鼎立,因为React背后的Facebook、Angular后面的Google还有Vue后面的开源社区,都不会放弃的。

要我说多一些选择挺好,技术这东西不需要垄断,各自按照自己的特点进化下去,因为各有特点,开发者可以根据自己应用的特点去选择。