本文为稀土技能社区首发签约文章,14天内制止转载,14天后未获授权制止转载,侵权必究!
导读
在前端快速开展的今日,组件遵从着咱们日常开发的方方面面,不管是针对事务封装的事务组件,仍是项目中依靠的第三方根底 UI 组件(Ant Design、Element、Iviewui…),亦或是依靠的前端结构(Angular、Inferno、Preact、Vue、React、snabbdom、virtual-dom…),它们都遵从着「组件化」的概念,而这一切「组件化」都是「高内聚、低耦合」思想下的产品。
高内聚、低耦合,是软件工程中的概念,是判断软件设计好坏的规范,主要用于程序的面向对象的设计。它的考量规范是类的内聚性是否高,耦合度是否低。意图是使程序模块的可重用性、移植性大大增强。
「组件化」开发已然成为前端主流开发方法,因为「组件化」开发在代码复用、提高团队功率方面有着无可比拟的优势,现在流行的 Vue、React、Angular 等等结构都是组件结构。所以毫不夸张的说 「组件化将会是前端的开展方向」。
有读者或许会疑惑,Vue、React、Angular 这些前端结构也是组件?答案是必定的,前端结构的本质也便是笼统的组件。从结果导向来看,无论什么结构归根结底最终都会编程成 Js、Css、Html,因为只要这样才干被浏览器“认识”。在结构的设计思想层面上,「组件化」也仅仅进行一些功用的笼统和代码的阻隔。
就当下而言,运用这些结构也会给咱们带来一系列问题,例如:
- 作者所在的部分一半的项目用的 Vue 技能栈,一半的项目用的 React 技能栈,遵从「高内聚、低耦合」的原则,咱们为这两套技能栈分别搭建了Vue UI 组件库和React UI 组件库。这两套 UI 组件库的功用简直毫无差异,可是要由两个团队来维护。适配这两个结构,将要消耗双倍的人力成本。
- 即使针对同一个技能栈,在面临版别晋级时,旧的组件库也会存在不可用的情况。比方:Vue 从 2.x 晋级到 3.x 版别,React从 17版别晋级到 18 版别, 之前封装的根底组件和事务组件都在新版别中就不能正常运用。一套组件库在同一个结构不同版别之间存在差异,乃至只能固定在某一个版别中运用,这自身于前端的「组件化」趋势是相违背的。
- 跟着前端复杂度的增加,项目中运用的结构越来越多,会在不经意间呈现款式的冲突。许多结构在组件设计时没有款式进行款式隔,例如:在运用 React 时,React 在书写组件款式时经常呈现款式掩盖、错乱的问题,不得不凭借其他计划来处理此类问题。
- Webpack 盛行的今日,大多数项目运用 Webpack 作为编译工具,这让组件经过 Webpack 编译之后想要在运行时即引即用变得不太实际。
- 前端结构的「组件化」并不是实在的「组件化」。尽管书写代码时的确是「组件化」的办法在写,可是编译完之后就不再「组件化」了。
- 「组件化」给前端的开发带来了极大的功率提高,跟着开展前端「组件化」的结构也因此层出不穷,从最早的 jQuery,再到 React、Vue、Angular、Ratchet、Ionic 等等,简直每年都有许多新的结构如雨后春笋悄然而生,它们或学习或颠覆其他已存在的结构,究其本质这些结构的很大一部分模块在功用上是重合的,但也仅仅在功用层面重合,代码层面确彻底不兼容。
为了处理这些问题,各种处理计划层出不穷,其间 Web Components
便是其间要害的一环。
Web Components 是什么?
Web Components 是一套不同的技能,答应您创立可重用的定制元素(它们的功用封装在您的代码之外)并且在您的 web 运用中运用它们。Web Components 也是一个浏览器原生支撑的组件化计划,答应你创立新的自界说、可封装的HTML 符号,运用时不必加载任何额定的模块。自界说组件和小部件根据 Web Components 规范构建,可跨现代浏览器作业,并可与任何支撑 HTML 的 JavaScript 库或结构一起运用。
其实简单了解 Web Components 便是:Web Components 是一套技能,答应创立可重用的自界说元素
而 Web Component 的意图也很明确,从原生层面完成组件化,使开发者开发、复用、扩展自界说组,完成自界说标签
。意味着前端开发人员开发组件时能够完成 Write once, run anywhere
。
Web Components 的组成
Web Components 自身不是一个单独的规范,也不是一门单一的技能,而是由一组 DOM API 和 HTML 规范所组成。它其间就包含了:
- ES Modules
- HTML templates
- Custom Elements
- Shadow DOM
ES Modules
ES Modules(ESM)信任我们十分熟悉了,作为组件的引进方法成为 Web Components 的规范之一。其实前期并不是运用的 ES Modules 作为 Web Components 的导入方法,而是 HTML Imports,惋惜 HTML Imports 现已被抛弃,假如想正常运用 HTML Imports 代码检查作用,能够安装低版别浏览器。
ES Modules(ESM)使 Web Components 能够以模块化方法开发,这与其他承受的 JavaScript 运用程序开发完成坚持一致。您能够在 JS 文件中界说自界说元素的接口,然后将其包含在 type=”module” 特点中。
HTML templates
HTML templates 运用 template 进行元素包裹,包裹的元素不会当即烘托,只要在内容有用的时分,才会解析烘托,具有这个特点后,咱们能够在自界说标签中按需增加咱们需求的模板,并在自界说标签烘托的时分再去解析咱们的模板,这样做能够在 HTML 有频频更改更新使命,或者重写符号的时分十分有用。
Custom elements
Custom elements 通过 CustomElementRegistry 来自界说能够直接烘托的 html 元素,并供给了组件的生命周期 connectedCallback
、disconnectCallback
、attributeChangedCallback
等供给给开发者聚合逻辑时运用。
Shadow DOM
Shadow Dom 被称为 影子DOM」 或 「隐式 DOM」,望文生义,具有躲藏特点,详细的意思便是说,在运用 Shadow DOM 的时分,组件标签内的 CSS 和 HTML 会彻底的隐式存在于元素内部,在详细页面中,标签内部的HTML 结构会存在于 #shdaow-root
,而不会在实在的 dom 树中呈现。其实这个 Shadow Dom并不陌生,在前端开发时运用的许多 HTML 标签中现已将它运用起来。例如常见的 video
标签。
Web Components 的历史
其实 Web Components 并不是近几年才呈现的规范。
最早在 2011 年的时分 Google 就推出了 Web Components 的概念,也算是前端开展的前期了。那时分前端还处于百废待兴的一个状态,前端乃至都没有「组件化」的概念,可是便是这个时分 Google 就现已凭明锐的嗅觉察觉到「组件化」是未来开展的趋势,所以提出了 Web Components 。不过在最开始时 Google 也仅仅提出了这样一个概念,并没有去完成它,所以并没有呈现太大的浪花。
2011 年 React 结构也诞生了。
到了 2013 年,Google 浏览器和 Opera 浏览器联合推出 Web Components 规范的 v0 版别。这也算是 Web Components 最早的版别了。
2013 年 React 结构开源。
2014 年 Vue 结构诞生,这儿为什么要说到 Vue 结构了?因为 Vue 作者在创立 Vue 的时分许多参考了 Web Components 的语法。
在 2016 年 2 月, Shadow DOM 和 Custom Element 被并入 DOM 规范规范里面,而不再作为独立的规范存在。
在 2017 年 Google I/O 上,Polymer 结构发布2.0 版别,而这次晋级的最主要意义便是将 Shadow Dom 和 Custom Elements 晋级到 v1 版别,然后取得更多浏览器支撑下一 代 Web Components 规范。
然后在 2018 年,Shadow DOM 和 Custom Element v2 在 Chrome、Safari、三星浏览器上现已支撑,还被 Firefox 列为要支撑的特性。
所以 Web Components 并不是一个新的概念,它现已存在很长时刻了,仅仅或许还没有全面的进入研发者的视界。
Web Components 开展趋势
尽管 Web Components 或许还没有全面的进入研发者的视界,现在还备受争议,可是它现已被许多大厂现已直接或者间接将它用于实践,比方:Twitter、YouTube、Electronic Arts、Adobe Spectrum、IBM 等等大厂(当然不止于此)。
在 Chrome 浏览器中对 customElements.define 至少调用一次的页面加载百分比统计也可看出 Web Components 现已适当流行。
data origin: chromestatus.com/metrics/fea…
再通过 Web Components 在 Chrome 浏览器的增加趋势也能够看出 Web Components 的增加十分亮眼。
data origin: chromestatus.com/metrics/fea…
并且在市场上也呈现了许多 Web Components 库,能够轻松的运用和构建 Web Components,例如:
- hybrids: 是一个 JavaScript UI 结构,用于创立功用完全的 Web 运用程序、组件库或具有独特的混合声明性和功用性架构的单个 Web Components。
- LitElement: 是一个简单的基类,用于运用 lit-html 创立快速、轻量级的 Web Components。
- Polymer :是 Google 推出的 Web Components 库,支撑数据的单向和双向绑定,兼容性较好,跨浏览器性能也较好;供给了一组用于创立 custom elements 的功用。这些功用旨在使 custom elements 像规范 DOM 元素一样作业更容易和更快。
- X-Tag: 是微软推出的开源库,支撑 Web Components 规范,兼容Web Components API。
- Slim.js: 是一个开源的轻量级 Web Components 库,它为组件供给数据绑定和扩展才能,运用 es6 原生类继承。专心于协助开发者更好的编写原生web组件,而不依靠于其他结构,可是也供给了杰出的拓宽性,开发者能够自由拓宽。
- Stencil: 是一个用于构建可重用、可扩展的设计系统的工具链。生成可在每个浏览器中运行的小型、极快且 100% 根据规范的 Web Components。
- Omi: 是 Web Components + JSX/TSX 交融为一个结构,小巧的尺度和高性能,交融和 React 和 Web Components 各自的优势。
Web Components 的优势
跟着前端的开展,前端以 React、Vue、Angular 为主的结构也日益完善,我们必定很奇怪,现在的前端结构不是挺好的吗?为什么咱们还需求 Web Components 了? 最大的原因在于 Web Components 建立在 Web 规范之上。
尽管结构组件很棒,但它们只在自己的生态系统中很棒。您不能(轻松)在 React 中运用 Angular 组件,也不能(轻松)在 React 中运用 Vue 组件,反之亦然。而 Web Components 建立在 Web 规范之上,它们将能够在所有生态系统中作业,这也决议了它有巨大的优势:
- 互操作性:组件能够超越结构并用于不同技能栈的多个项目中。
- 组件寿数:组件是可互操作的,这也决议了 Web Components 的组件寿数会更长,并不需求考虑技能栈版别晋级到来的不兼容问题。
- 可移植性:组件能够在简直没有依靠关系的任何地方作业。因为它是原生,运用障碍明显低于组件依靠库或结构。
除此之外,Web 组件还具有向下的穿插兼容性,这关于跟着不断变化的 Web 环境向前开展至关重要。
Web Components 的约束
尽管 Web Components 有着巨大的优势,可是也存在一些约束,假如你正在运用它,那请注意了。例如:
- Web Components 供给的
CSS 封装是有限
。 - 尽管能完成 CSS 的阻隔,可是阻隔也会导致和
外部 CSS 交互比较难
。 -
Object.prototype.toString
不返回与原生对象相同的字符串。 -
document
、window
、document.body
、document.head
是不可装备的,不能被掩盖。 - 未完成跨窗口/结构拜访。
- CSS:host()规矩在其参数选择器中只能(最多)有一层嵌套括号。例如,:host(.zot)两者:host(.zot:not(.bar))都有用,但:host(.zot:not(.bar:nth-child(2)))没有。
最终
Web Components 优势明显,能彻底改变 Web 的开发,可是现在来说还需时日,需求做许多作业才干使 WebComponents 变得实在优异,才干让我们享受到「组件化」 Web 开发的便当。但请我们不要混淆,Web Components 并不是为了替代任何现有结构而生,Web Component 的意图是为了从原生层面完成组件化,能够使开发者开发、复用、扩展自界说组件,完成自界说标签
,处理 Web 组件的重用和同享问题,并使 Web 生态坚持持续的开放和统一。
参考
- fronteers.nl/congres/201…
- www.webcomponents.org/
- developer.mozilla.org/zh-CN/docs/…
- baike.baidu.com/item/%E9%AB…
- baike.baidu.com/item/%E7%BB…
- /post/684490…
- baijiahao.baidu.com/s?id=172572…
- /post/684490…
- github.com/hybridsjs/h…
- github.com/lit/lit-ele…
- polymer-library.polymer-project.org/3.0/docs/de…
- slimjs.com/#/welcome
- x-tag.github.io/
- github.com/Tencent/omi
- blog.revillweb.com/why-web-com…
- chromestatus.com/metrics/fea…
- developer.mozilla.org/zh-CN/docs/…
- www.webcomponents.org/polyfills
- www.webcomponents.org/specs#the-h…