本期精读的文章是:The broken promise of Web Components
以及对这篇文章的回应: Regarding the broken promise of Web Components
1 引言
我为什么要选这篇文章呢?
就在前几天的 Google I/O 2017 上, Polymer 正式发布了 Polymer 2.0 版本.
来看一下 Polymer 2.0 的一些变化:
- 使用 Shadow DOM v1 代替 Polymer.dom. Shady DOM 从 Polymer 中分离出来。
- 使用 标准的 ES6 类和 Custom Elements v1 来自定义元素.
- 还有数据系统的改进和生命周期的变更.
可以看到, Polymer 的这次升级主要是将 Shadow Dom 和 Custom Elements 升级到 v1 版本, 以获得更多浏览器的原生支持. 下一 代 Web Components - v1 规范,Chrome 已经支持了,Web Components 规范中的 2 个主要部分 - Shadow Dom 和 Custom Elements. Safari 在 10 版本中, 支持了 Shadow DOM v1 规范并且完成了在 Webkit 内核中对 Custom Elements v1 规范的实现;Firefox 对 Shadow DOM 和 Custom Elements v1 规范 支持正在开发中;Edge 也将对 Shadow DOM 和 Custom Elements 支持规划到他们的开发 roadmap 中。
这段时间, 大家都在讨论 react, vue, angular, 这些框架. 或者 该使用 redux 还 是 mobx 做数据管理. 在这个契机下, 我想我们可以不单单去思考这些框架, 也可以更多地去思考和了解 Web Components 标准. 对于 Web Components 标准有一些思考. 所以我选了一篇关于 Web Components 的文章, 想让大家对于 Web Components 的发展, 和 Web Componets 与现在的主流框架如何协作有更多的思考和讨论.
2 内容概要
The broken promise of Web Components
原文作者 dmitriid 主要是在喷 Web Components 从 2011 年到 2017 年这 6 年间毫无进展, 一共产出了 6 份标准, 其中两份已经被弃用. 几乎只有一个主流浏览器(chrome) 支持.
- Web Components 这些规范强依赖 JS 的实现
- Custom Elements 是 JS 脚本的一部分
- HTML Templates 的出现就是为了被 JS 脚本使用
- Shadow Dom 也需要配合 JS 脚本使用
- 只有 HTML imports 可以脱离 JS 脚本使用
- Web Components 操作 DOM
- 属性都是字符串
- 元素的内容模型(Content Model)比较奇怪
- 为了突破限制使用不同的方法来传递数据
- CSS 作用域, 可以见上次精读《请停止 css-in-js 的行为》
来看一下 Polymer 的 核心成员 Rob Dodson 对于本文的回应: Regarding the broken promise of Web Components
- Web Components 特性需要被浏览器支持,必须有平缓的过渡,良好的兼容,以及成熟的方案,因此推进速度会比较慢一些。
- React 很棒, 但是也不要忽略其他基于 Web Components 的优秀库比如 Amp
- 对于 DOM 更新的抽象比如 React/JSX 很赞, 但是也带来了一些损耗. 在旧的移动设备上, 加载一个大的 js 包性能依旧不理想, 最佳的做法是拆分你的 JS 包, 按需加载.
- 使用 JSX 和 虚拟 DOM 是很酷, 也可以直接把 JSX 用在 Web Components 内, 像SkateJS库, 已经在做这个事情了.
- 没有标准的数据绑定, Polymer 的数据绑定, 现在是基于MDV, 很多开发者更倾向于基于 Observables 或者 ES6 Proxies 的数据绑定方案.
- 处理组件的字符串属性是很烦人, 但是由于每一个组件都是一个类的实例, 可以利用 ES6 的 getters/setters 来改变属性.
Rob Dodson 对于 Web Components 依然充满信心, 但是也承认推进标准总会有各种阻碍, 不可能像推荐框架一样快速把事情解决.
3 精读
标准与框架
Web Components 作为一个标准,骨子里的进度就会落后于当前可行的技术体系。正如文中所说,浏览器厂商 ship 一个新功能是很严肃的,很可能会影响到一票的线上业务,甚至会影响到一个产业(遥想当年 Chrome Extension 禁用 NPAPI时的一片哀鸿遍野,许多返利插件都使用了这种技术)。那么 Web Components 的缓慢推进也在情理之中了.
即使真的有一天这个标准建立起来,Web Components 作为浏览器底层特性不应该拿出来和 React 这类应用层框架相比较. 未来 Web Components 会做为浏览器非常重要的特性存在。API 偏低层操作,会易用性不够. 在很长时间内开发者依旧会使用 React/Vue/Angular/Polymer 这样的框架,Web Components 可能会做为这些框架的底层做一些 浏览器层面上的支持.
不需要 vendor 的自定义组件间调用
在 Webpack 大行其道的时代,想在运行时做到组件即引即用变得很困难,因为这些组件大多是通过 React/Vue/Angular 开发的。不得不考虑引入一大堆 Vendor 包,这些 Vendor 里可能还必须包含 React 这类两个版本不能同时使用的库。目前我们团队在做组件化方案时就遇到这个问题,只能想办法避免两个版本的出现。你可以说这是 React 或 Webpack 引入的问题,但并没有看到 Web Compnents 标准化的解决方案。我想未来 Web Components 可能会作为浏览器的底层, 出现基于底层的标准方案来做组件间的相互应用的方法.
为什么对 Web components 讨论不断
俗话说,成也萧何,败也萧何。正如原文提及的,现在网页规模越来越大,需求也越来越灵活,html 与 css 的能力已经严重不足,我们才孤注一掷的上了 js 的贼船:JSX 和 Css module,因为 Web components 依托在 html 模版语言上,当然没办法与 js 的灵活性媲美。
但使用前端框架的问题也日益暴露,随着前端框架种类的增多,同一个框架不同版本之间无法共存,导致组件无法跨框架复用,甚至只能固定在框架的某个版本,这与前端未来的模块化发展是相违背的,我们越是与之抗衡,就越希望 Web components 能站出来解决这个问题,因为浏览器原生支持模块化,相当于将 react angular vue 的能力内置在浏览器中,而且一定会向前兼容(这也是 Web components 推进缓慢的原因)。
4 总结
我觉得 Web Components 作为浏览器底层特性不应该拿出来和 React, vue 这类应用层框架相比较. Web Components 的方向以及提供的价值都不会跟 应用框架一致. 而 Web Components 作为未来的 Web 组件标准 , 它在任何生态中都可以运行良好. 我倒是更加期待应用层去基于 Web Components 去做更多的实现, 让组件超越框架存在, 可以在不同技术栈中使用.
讨论地址是:精读《Web Components 的困境》 · Issue #15 · dt-fe/weekly