本期精读的文章是：[The broken promise of Web Components
](https://dmitriid.com/blog/2017/03/the-broken-promise-of-web-components/)

以及对这篇文章的回应: [Regarding the broken promise of Web Components](https://robdodson.me/regarding-the-broken-promise-of-web-components/)

# 1 引言

我为什么要选这篇文章呢？

就在前几天的 Google I/O 2017 上, Polymer 正式发布了 [Polymer 2.0](https://www.polymer-project.org/blog/2017-05-15-time-for-two) 版本. 

来看一下 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](https://www.chromestatus.com/feature/4667415417847808) 和 [Custom Elements](https://www.chromestatus.com/feature/4696261944934400). Safari 在 10 版本中, 支持了 [Shadow DOM v1](https://webkit.org/status/#feature-shadow-dom) 规范并且完成了在 Webkit 内核中对 [Custom Elements v1](https://webkit.org/blog/7027/introducing-custom-elements/) 规范的实现；Firefox 对 [Shadow DOM](https://platform-status.mozilla.org/#shadow-dom) 和 [Custom Elements v1 规范](https://platform-status.mozilla.org/#custom-elements) 支持正在开发中；Edge 也将对 [Shadow DOM](https://developer.microsoft.com/en-us/microsoft-edge/platform/status/shadowdom/) 和 [Custom Elements](https://developer.microsoft.com/en-us/microsoft-edge/platform/status/customelements/) 支持规划到他们的开发 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) 支持. 

![image](https://dmitriid.com/assets/img/blog/web-components-support.png)


- Web Components 这些规范强依赖 JS 的实现
    - Custom Elements 是 JS 脚本的一部分
    - HTML Templates 的出现就是为了被 JS 脚本使用
    - Shadow Dom 也需要配合 JS 脚本使用
    - 只有 HTML imports 可以脱离 JS 脚本使用
- Web Components 操作 DOM
    - 属性都是字符串
    - 元素的内容模型(Content Model)比较奇怪
- 为了突破限制使用不同的方法来传递数据
- CSS 作用域, 可以见上次精读[《请停止 css-in-js 的行为》](https://github.com/dt-fe/weekly/issues/12)

**来看一下 Polymer 的 核心成员 Rob Dodson 对于本文的回应: Regarding the broken promise of Web Components**

- Web Components 特性需要被浏览器支持，必须有平缓的过渡，良好的兼容，以及成熟的方案，因此推进速度会比较慢一些。
- React 很棒, 但是也不要忽略其他基于 Web Components 的优秀库比如 [Amp](https://www.ampproject.org/)
- 对于 DOM 更新的抽象比如 React/JSX 很赞, 但是也带来了一些损耗. 在旧的移动设备上, 加载一个大的 js 包性能依旧不理想, 最佳的做法是拆分你的 JS 包, 按需加载. 
- 使用 JSX 和 虚拟 DOM 是很酷, 也可以直接把 JSX 用在 Web Components 内, 像[SkateJS](https://github.com/skatejs/skatejs)库, 已经在做这个事情了.
- 没有标准的数据绑定, Polymer 的数据绑定, 现在是基于[MDV](https://github.com/toolkitchen/mdv), 很多开发者更倾向于基于 Observables 或者 ES6 Proxies 的数据绑定方案.
- 处理组件的字符串属性是很烦人, 但是由于每一个组件都是一个类的实例, 可以利用 ES6 的 getters/setters 来改变属性. 

Rob Dodson 对于 Web Components 依然充满信心, 但是也承认推进标准总会有各种阻碍, 不可能像推荐框架一样快速把事情解决. 

# 3 精读

本次提出独到观点的同学有：
[@camsong](https://www.zhihu.com/people/078cc0fb15845759ad8295b0f0e50099)  [@黄子毅](https://github.com/ascoders) [@杨森](https://www.zhihu.com/people/c93b7957f6308990c7e3b16103c9356b) [@rccoder](https://github.com/rccoder) [@alcat2008](https://github.com/alcat2008)精读由此归纳。

### 标准与框架
Web Components 作为一个标准，骨子里的进度就会落后于当前可行的技术体系。正如文中所说，浏览器厂商 ship 一个新功能是很严肃的，很可能会影响到一票的线上业务，甚至会影响到一个产业（遥想当年 [Chrome Extension 禁用 NPAPI](https://blog.chromium.org/2013/09/saying-goodbye-to-our-old-friend-npapi.html)时的一片哀鸿遍野，许多返利插件都使用了这种技术）。那么 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](https://github.com/dt-fe/weekly/issues/15)

> 如果你想参与讨论，请[点击这里](https://github.com/dt-fe/weekly)，每周都有新的主题，每周五发布。

