【转】组件化的Web王国

本文由 埃姆杰 翻译。未经许可,禁止转载!
英文出处:Future Insights

内容提要

使用许多独立组件构建应用程序的想法并不新鲜。Web Component的出现,是从新回顾基于组件的应用程序开发模式的好时机。咱们能够从这个过程当中受益,了解如何使用现有技术完成目标,而且在将来作出本身的前端Web应用。html

什么是组件?

软件开发是一个语义丰富(术语一般不止一个意思)的领域。很显然,这里的“组件”是一个很泛的称呼,因此有必要指明咱们想要表达的,在前端Web应用的语言环境中的意思。前端

前端Web应用中的组件,是指一些设计为通用性的,用来构建较大型应用程序的软件,这些组件有多种表现形式。它能够是有UI(用户界面)的,也能够是做为 “服务”的纯逻辑代码。html5

由于有视觉上的表现形式,UI组件更容易理解。UI组件简单的例子包括按钮、输入框和文本域。不管是汉堡包状的菜单按钮(不管你是否喜欢)、标签页、日历、选项菜单或者所见即所得的富文本编辑器则是一些更加高级的例子。react

提供服务类型的组件可能会让人难以理解,这种类型的例子包括跨浏览器的AJAX支持,日志记录或者提供某种数据持久化的功能。git

基于组件开发,最重要的就是组件能够用来构成其余组件,而富文本编辑器就是个很好的例子。它是由按钮、下拉菜单和一些可视化组件等组成。另外一个例子是HTML5上的video元素。它一样包含按钮,也同时含有一个能从视频数据流渲染内容的元素。angularjs

为何要构建组件?

既然如今已经明白组件的意思,就看看使用组件的方法构建前端应用的好处。github

模块

你可能据说过 “组件是自然模块”的说法。好吧,感谢它,咱们又要解释这里的术语!web

你可能会以为“组件”的说法更加适合用来描述UI,而“模块”更适合描述提供服务的功能逻辑。而对于我来讲,模块和组件意思相近,都提供组织、聚焦和封装,是与某个功能单位相关的。npm

高内聚

又是一个软件工程的高频词! 咱们将相关的一些功能组织在一块儿,把一切封装起来,而在组件的例子中,就多是相关的功能逻辑和静态资源:JavaScript、HTML、CSS以及图像等。这就是咱们所说的内聚。浏览器

这种作法将让组件更容易维护,而且这么作以后,组件的可靠性也将提升。同时,它也能让组件的功能明确,增大组件重用的可能性。

可重用

你看到的示例组件,尤为是Web Component,更关心可重用的问题。功能明确,实现清晰,API易于理解。天然就能促进组件复用。经过构建可重用组件,咱们不只保持了 DRY(不要重复造轮子)原则,还获得了相应的好处。

这里要提醒: 不要过度尝试构建可重用组件。你更应该关注应用程序上所须要的那些特定部分。若是以后相应需求出现,或者组件的确到了可重用的地步,就花一点额外时间让组件重用。事实上,开发者都喜欢去创造可重用功能块(库、组件、模块、插件等),作得太早将会让你后来痛苦不堪。因此,吸收基于组件开发的其余好处,而且接受不是全部组件都能重用的事实。

可互换

一个功能明确好组件的API能让人轻易地更改其内部的功能实现。要是程序内部的组件是松耦合的,那事实上能够用一个组件轻易地替换另外一个组件,只要遵循相同的 API/接口/约定

假如你使用GoInstant提供的实时功能服务组件,那他们这周关闭服务这样的新闻会影响到你。然而,只要提供了相同的数据同步API,你也能够自行构建使用一个 FirebaseComponent 组件或者 PubNubComponent 组件。

可组合

以前也讨论过,基于组件的架构让组件组合成新组件更加容易。这样的设计让组件更加专一,也让其余组件中构建和暴露的功能更好利用。

不管是给程序添加功能,仍是用来制做完整的程序,更加复杂的功能也能如法炮制。这就是这种方法的主要好处。

是否有必要把全部的东西转换成组件,事实上取决于你本身。没有任何理由让你的程序由 你本身 的组件组合成你最惊叹的功能 ,乃至 最花哨的功能。而这些组件又反过来构成其余组件。若是你从这个方法中获得了好处,就千方百计地去坚持它。然而要注意的是,不要用一样的方法把事情变得复杂,你并不须要过度关注如何让组件重用。而是要关注呈现程序的功能。

如今就开始构建组件

在 Caplin Systems 构建基于组件的自有应用程序时,我用到了几条原则和实践。这些原则由 BladeRunnerJS(BRJS) 开源工具集支撑。它被称做”BladeRunnerJS” 是由于咱们将程序功能都封装在称做 Blades 的东西中。Blade是能够在某个应用中重用的功能特性,可是不能够在程序间重用。当功能 真的 变得更加通用的时候,咱们将相应的定义移到库文件中,供各个程序间使用。特定应用中的组件(blade)和咱们程序间的通用组件可使用,咱们只要找到最好知足需求的任何库和框架。

那么,如今什么库和框架可以帮助咱们构建组件呢?

在决定构建应用时应使用何种技术时,只须要看看流行的 TodoMVC 网站就能够看到大量可供选择的前端库和框架。你也许会以为任何一种方案都能用来构建基于组件的应用程序。然而,他们之中的一些方案内置了对组件的支持。其中比较有名的是AngularJS、Ember 和 React。

组件间是如何通讯的?

在深刻示例以前有必要简单地提到组件间通讯的问题。若是组件之间是“独立”、“模块化”的,他们又是如何相互通讯的呢?

最显而易见的答案就是让组件间相互引用并经过他们之间的API交互。这样作的问题就在于,这种作法会让组件相互依赖。短时间内可能还好,一段时间之后,你在修改程序的时候程序会失控,修改一个组件就会对另外一个组件产生极大的影响。决定移除一个不能带来预期价值组件可能会让你的应用程序中止工做,由于它背后会有数个组件依赖于它。

此时,解决方案是提供松耦合的,让组件之间不多或者几乎不知道彼此的方案。组件并不直接建立其余组件,在他们须要通讯的时候,他们经过“接口/约定”或者经过 服务。咱们在构建BRJS程序时考虑了不少这些方面的东西,而且使用 ServiceRegistry 访问用于组件间通信的服务或者是Web API这样的资源。Angular和Ember采用了服务和依赖注入解决这类问题。

示例组件my-avatar

为了展现咱们如何用这些库和框架构建最基本的组件,咱们创建了一个带有UI,用于取回和显示用户头像的简单示例。在可能的状况下,该组件会有 my-avatar 标签,会从如下两个属性中取得头像:

  • service 容许设置一个服务。例如 twitter 或者 facebook
  • username 用于取回该用户名相对应的头像

AngularJS

AngularJS 多是如今用于构建程序最流行的前端解决方案了。做为建立者的Google,从新思考HTML,考虑如何从新发明,知足现在Web开发的须要。

Angular中可使用自定义指令定义组件。以后,你可使用 HTML 标记声明自定义组件。

查看代码演示: http://jsbin.com/lacog/2/edit

这个例子展现了使用Angular指令的简单程度。值scope 定义了从  my-avatar 元素中取得,而且以后用来构建相应的img标签和渲染成用户头像的属性。

Ember

框架与库的争论旷日持久,总的来讲框架是强制你按某种方式作事情,因此它是邪恶的。很显然,Angular是个框架,而Ember的做者,Yehuda Katz和Tom Dale也很乐意把Ember看做框架

Ember 有对它称做组件的内建支持。Ember Components背后的理念是尽量的向Web Components看齐,当浏览器支持容许时,就能够很方便地迁移到Web Components中。

查看代码演示: http://jsbin.com/nawuwi/4/edit

上面的例子中使用了 handlebars 作模板,因此元素的定义不是同一种语法。

React

React 虽然是个新人,可是却已经有不少的追随者。它由Facebook开发,而且已经全面用于Instagram的UI和部分Facebook的UI。

使用React构建组件的推荐方式是使用叫作 JSX 的东西来定义它们。这是一种“推荐在React上使用的JavaScript语法转换”。请不要所以分心。他们已经在文档中指出,这个想法就是用来帮助你在JavaScript中写出HTML标记的。

我不是说你并不能够直接在HTML中添加标签,而必须使用JSX建立本身的组件。可是,只要你定义了一个组件,你就可使用这个组件创造其余组件。

查看代码演示: http://jsbin.com/qigoz/5/edit

所以,组件使用的声明语法须要相应的HTML元素和对 React.RenderComponent 的调用。

将来:Web Component和其余

Web Component才是将来!正如名字所表示的那样,他们承诺将带来能够将功能封装成组件的浏览器原生支持。

我将简单展现Web Component而且演示咱们如今能够如何使用它。更加深刻的内容请参考本文末尾的 “外部资源” 一节。

他们提供的功能包括:

自定义元素

咱们在上面关注的是用Angular、Ember和React构建 my-avatar 的例子。可能的状况下,这样的方式将以页面上或者模板上添加的自定义元素表示。Web Component包括经过自定义元素得到的原生支持 – 绝对是Web Component标准的基本组成部分。

定义新元素,包括访问元素生命周期的部分事件例如什么时候建立(createdCallback)、什么时候添加在DOM树上(attachedCallback)、什么时候从DOM树上分离(detachedCallback),什么时候元素属性改变(attributeChangedCallback(attrName, oldVal, newVal))。

自定义元素的一个重要的部分就是有能力从原有元素扩展,于是获得原有元素相应的功能。示例中咱们扩展了 <img>元素 。

最终,咱们所写的代码中,自定义元素正在而且倾向去作的就是将复杂的东西抽象化,让用户关注于单个组件产生的价值,从而用来构建更加丰富的功能。

Shadow DOM

还记得iframe们吗?咱们还在使用它们,是由于他们能确保组件和控件的JavaScript和CSS不会影响页面。 Shadow DOM 也能提供这样的保护,而且没有iframe带来的负担。正式的说法是:

Shadow DOM的设计是在shadow根下隐藏DOM子树从而提供封装机制。它提供了创建和保障DOM树之间的功能界限,以及给这些树提供交互的功能,从而在DOM树上提供了更好的功能封装。

HTML导入

咱们长时间之前就能够导入JavaScript和CSS了。 HTML导入功能提供了从其余HTML文档中导入和重用HTML文档的能力。这种简单性同时意味着能够很方便地用一些组件构建另外一些组件。

最后,这样的格式很理想,适合可重用组件,而且能够用你最喜欢的包管理解决方案发布(例如: bower、 npm 或者 Component)。

模板

咱们中的许多人已经使用像handlebars、mustache或者underscore.js中的模板这样的解决方案(就像咱们在上面的Ember示例中用的同样)。Web Component经过 template元素 提供了模板的原生支持

原生模板让你能够声明分类为“隐藏DOM”可是解析成HTML的标记片断。他们在页面加载时没有用处,可是能够在运行时实例化。他们能够 被检索到 ,可是在插入活动的DOM树前不会加载任何相关资源。

Platform.js

可是,就像每次提到新特性同样,咱们不能肯定浏览器是否支持这些特性。

截至2014年6月27日,Web Component 的浏览器支持状况

一样,咱们也能经过一些神奇的兼容代码,开始使用某些Web Component所提供的功能。

有了兼容库的Web Component支持状况

好消息是两个最早进的浏览器厂商Google和Mozilla正在努力完善兼容库 ,帮助咱们使用Web Component。

如下示例展现使用platform.js后咱们能够如何定义做为img元素扩展的my-avatar元素。最棒的是它能用到原生img元素的全部功能。

查看代码演示: http://jsbin.com/pihuz/4/edit

点击 HTML5 Rocks Custom Elements tutorial 以查看建立自定义元素的更多信息。

注:若是你对platform.js感兴趣,也能够看看 bosonic

原生技术的支持目的就是给咱们提供相应的构建基础。因此Web Component并非库和框架的末日信号。

Polymer

Polymer 是演示构建基于原生Web Component功能的最佳示例。它提供了精选的机制用来建立自定义的Polymer元素,而且提供了许多核心的UI组件,让你能够建立本身的应用程序。

下面你能够看到 my-avatar 元素的简单建立过程,同时咱们也获得了想要的标记。

查看代码演示: http://jsbin.com/gukoku/2/edit

Google正在大力推进Polymer。请查看 Polymer getting started guide 查看更多示例。

X-Tag和Brick

Mozilla开发了本身的自定义元素 兼容库,叫作 X-Tag。X-Tag是一个为启用Web Component进行多项兼容的库,并即将提供对Web Component的完整支持。

如下就是使用X-Tag的 my-avatar 自定义组件,与标准文档十分相似:

查看代码演示:http://jsbin.com/wexiz/2/edit

Mozilla同时还创造了一个叫 Brick 的库,其中包括X-Tag,提供“一组用来方便快速构建Web应用程序的UI组件”,使用与Google的Polymer类似的方式。

总结

使用基于组件的架构构建应用程序有诸多好处,你能从现有的框架中学到,也能在构建前端Web应用程序时从推荐的Web Component中学习到。

这场组件化Web王国的旅程,让咱们在面临框架和工具的选择时犹豫不决。可是,Web Component会是最后的明灯!

Web Component会提供构建应用程序的原生统一的方法。现有的框架颇有可能会转而使用Web Component或者说明如何与它一同使用。Ember的策略是让迁移到Web Component更加方便,而Facebook的React则是演示整合的好例子,已经有一个 ReactiveElements 演示它了。由于Angular和Polymer都是Google的项目,他们颇有可能会走到一块儿。

外部资源(英文)

相关文章
相关标签/搜索