本期精读的文章是:[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),每周都有新的主题,每周五发布。