引子
上一次社区中谈论起 Web Components 已经可以追溯到三四年前了,彼时 Web Components 仍处于不稳定的草案阶段,Polymer 的出世使大家似乎看到了新一代的前端技术,但直到今天,在今年五月 Google I/O 发布 Polymer 3 之后, Web Components 的规模化应用才看似成为了可能。
过去一段时间,我一直在使用 Web Components 构建淘宝小程序的 基础组件 Atag。MDN 上对 Web Components 这个名词的解释是
Web Components是一套不同的技术,允许您创建可重用的定制元素(它们的功能封装在您的代码之外)并且在您的web应用中使用它们。
我们从中提取几个关键字:可重用
定制元素
封装
这些特性刚好能满足可复用组件的需求,更重要的是,这是由 W3C 标准提供的,面向标准编程不需要再考虑我使用的技术在未来几年内会不会过时。目前社区中的框架大都具有传染性,什么是传染性?如果你希望使用一个 React 组件,大概率你的整个用户界面都会使用 React 来开发。而 Custom Elements 不是这样,因为它替代的是 div
,能使用 div
的地方就能使用它,它即插即用:引入一个 js
文件就可以了,直接操作 DOM 使它的性能更高,它并不跟社区主流的框架相克,这样看来它更适合用来开发底层的基础组件。
回到正题,这篇文章的目的,是希望总结在 Atag 开发阶段中使用 Web Components 的经验,避免大家踩坑。
基础设施
webcomponentsjs
Github 地址
这是一系列 Web Components 规范的 polyfill 集合,如果你的目标用户不是最新的现代浏览器,强烈建议引入这个库。
引用方式 :
建议在 html 中使用 script 标签引入它,而不是通过 npm 引入,这样浏览器可以使用缓存帮助你减少二次加载的消耗。
(以下引入方式二选一)
- 使用 bundle 整包引入,这样会引入整个库中包含的所有 polyfills。
- 如果你需要按需引入 bundle,这个库的 bundles 目录下有一系列预打包好的 bundle 文件,用后缀标明了它包含的功能:ce 表示 custom-elements,sd 表示 shadow-dom,pf 表示环境的 polyfills。
- [推荐] 使用 loader 按需引入,引入
webcomponents-loader.js
后,它会根据浏览器中的特征按需加载。
这里有必要对一些名词做一些解释:
- ShadyDOM 这是 Shadow DOM 的 polyfill 的官方名称,它通过劫持 HTMLElement 的原型方法来实现一些 Shadow DOM 节点拥有的功能,实际上它的原理是把节点添加到了真实(light) DOM 节点之上。
- ShadyCSS 跟上面一样,这也是 polyfill 的名称,它提供了一些 Shadow DOM 节点内样式的封装,使得可以在真实 DOM 中模拟 scoped style 的效果。它的原理是通过解析和重写 style 节点内部的样式规则来实现的。
需要注意的是,在引入 polyfill 的同时,有一些功能是无法被模拟的,需要我们在使用的时候避开,在下文中会介绍到。
NOTE: 这个库的 2.1.x 版本对 Symbol 的 polyfill 有一些问题,在官方修复之前建议使用 2.0.4 的稳定版本。
这里提供一份 alicdn 的 bundle URL: