澳门新葡萄京官网注册 1

原标题:GitHub已完全弃用jQuery,问题是为什么?

Bootstrap 最新版本 4.3.1
已发布,作为
Bootstrap 4.3 发布的一部分,团队也公布了下一个主要版本 Bootstrap 5
的开发计划。

澳门新葡萄京官网注册 2

澳门新葡萄京官网注册 3

开发团队表示在发布 v4.3 版本后,将会在开发 Bootstrap 5
的过程中实现一些关键变化,或许会是重大的变化,而这也将被认为是 Bootstrap
5 的基础
。开发团队重点提到了以下几方面:

澳门新葡萄京官网注册,值得一提的是,GitHub 前端团队并未使用其它框架来代替 jQuery,而是使用原生
JS:

作者 | GitHub 前端工程团队

  • 放弃 jQuery:Bootstrap 5 将删除 jQuery
    作为依赖项。开发团队已经在这方面工作了很长时间,PR
    也是处于正在进行中并已接近完成的状态()

  • 改进开发分支:v3-dev 分支将成为 master 分支;v4-dev
    则保持原样,不过会从该分支切出一个新的 master 分支来开发 v5 版本

  • 从 Jekyll 迁移到 Hugo:目前已有一个 PR 正在进行并且已接近完成

    ()

  • 用 querySelectorAll 来查询 DOM 节点;

  • 使用 fetch 代替 ajax(在不支持的浏览器上使用 XHR);

  • 使用代理事件来进行事件处理;

  • 为一些尚未实现的 DOM 标准写了 polyfill;

  • 更多的使用自定义元素(CustomElement)。

译者 | 无明

移除 jQuery 这个最大的依赖之后,开发团队表示未来将使用原生的纯
JavaScript 来代替 jQuery。这和去年 GitHub 改版重构页面时移除了 jQuery
的举措有点像。

他们把其中的一些成果也在 GitHub 上开源了:

编辑 | 覃云 – 前端之巅

当时 GitHub 的前端团队趁着改版的机会,在重构页面时乘机移除了其中的
jQuery,并且没有使用其它框架来代替 jQuery,而是使用原生 JavaScript:

Fetch polyfill:

最近,我们将 jQuery 完全从 GitHub.com
的前端代码中移除了,这标志着我们数年来逐步移除 jQuery
这个渐进式的过程终于结束了,这对我们来说是一件里程碑式的事件。这篇文章将介绍过去我们是如何依赖上
jQuery
的,随着时间地推移,我们意识到不再需要它,但到最后我们并没有使用另一个库或框架取代它,而是使用标准的浏览器
API 实现了我们所需要的一切。

  • 用 querySelectorAll 来查询 DOM 节点

  • 使用 fetch 代替 ajax(在不支持的浏览器上使用 XHR)

  • 使用代理事件来进行事件处理

  • 为一些尚未实现的 DOM 标准写了 polyfill

  • 更多地使用自定义元素 (CustomElement)

Delegated events:

早期,jQuery 对我们意义重大

澳门新葡萄京官网注册 4

Custom Elements:

GitHub.com 在 2007 年底开始使用 jQuery 1.2.1,那是谷歌发布 Chrome
浏览器的前一年。当时还没有通过 CSS 选择器来查询 DOM
元素的标准方法,也没有动态渲染元素的样式的标准方法,而 Internet Explorer
的 接口与其他很多 API 一样,在浏览器之间存在不一致性问题。

澳门新葡萄京官网注册 5

jQuery
曾风靡一个时代,大大降低了前端开发的门槛,丰富的插件也是前端开发者得心应手的武器库,但是,这个时代终于要落幕了。随着
JS 标准和浏览器的进步,jQuery 的很多精华被原生 JS 吸收,我们直接使用原生
API 就可以用类似手法来处理以前需要 jQuery 的问题。在新的 Web
项目中,如果不需要支持过于陈旧的浏览器版本,那么的确没有必要使用
jQuery。

jQuery 让 DOM 操作、创建动画和“AJAX”请求变得相当简单,基本上,它让 Web
开发人员能够创建更加现代化的动态 Web 体验。最重要的是,使用 jQuery
为一个浏览器开发的代码也适用于其他浏览器。在 GitHub 的早期阶段,jQuery
让小型的开发团队能够快速进行原型设计并开发出新功能,而无需专门针对每个
Web 浏览器调整代码。

澳门新葡萄京官网注册 6

但是,像 GitHub 这样重构掉 jQuery 有必要吗?

基于 jQuery 简单的接口所构建的扩展库也成为 GitHub.com
前端的基础构建块:pjax(
facebox(

可以看到,在 Bootstrap 5 中移除 jQuery 这个 PR
从提出到今天已经经历了一年半的时间,目前包含了 74 个 commits,正处于
Open 的状态,还有待解决的冲突。

到底要不要重构掉 jQuery?

我们将永远不会忘记 John Resig 和 jQuery
贡献者创建和维护的这样一个有用的基本库。

(文/开源中国)    

在微博上,有人指出其实没必要对旧项目进行大改:

后来的 Web 标准

澳门新葡萄京官网注册 7

多年来,GitHub
成长为一家拥有数百名工程师的公司,并逐渐成立了一个专门的团队,负责 Java
代码的规模和质量。我们一直在排除技术债务,有时技术债务会随着依赖项的增多而增长,这些依赖项在一开始会为我们带来一定的价值,但这些价值也随着时间的推移而下降。

对于没有更多需求的项目,的确没有必要大动干戈,但是,GitHub
是一个仍在继续迭代,不断有新功能模块推出的大型项目。通过改版的机会进行重构、切换技术栈,是目前互联网行业比较通常的做法。

我们可以将 jQuery 与现代浏览器支持的 Web 标准的快速演化进行比较:

在重构的过程中当然会引入新的问题,但如果比较一下收益,比如组件化、工程化的引入,对后续维护、持续的用户体验优化带来的好处,还是值得这么做的。

  • $(selector) 模式可以使用 querySelectorAll() 来替换;
  • 现在可以使用 Element.classList 来实现 CSS 类名切换;
  • CSS 现在支持在样式表中而不是在 Java 中定义可视动画;
  • 现在可以使用 Fetch Standard 执行 $.ajax 请求;
  • addEventListener() 接口已经足够稳定,可以跨平台使用;
  • 我们可以使用轻量级的库来封装事件委托模式;
  • 随着 Java 语言的发展,jQuery 提供的一些语法糖已经变得多余。

最后,jQuery
也并不是不能用了,它仍然是开发前端网页的一个选择,至于到底如何抉择,则要看当前场景是否适合了。

另外,链式语法不能满足我们想要的编写代码的方式。例如:

来自:前端之巅

$(‘.js-widget’) .addClass(‘is-loading’) .show()

这种语法写起来很简单,但是根据我们的标准,它并不能很好地传达我们的意图。作者是否期望在当前页面上有一个或多个
js-widget 元素?另外,如果我们更新页面标记并意外遗漏了 js-widget
类名,浏览器是否会抛出异常会告诉我们出了什么问题?默认情况下,当没有任何内容与选择器匹配时,jQuery
会跳过整个表达式,但对我们来说,这是一个 bug。

最后,我们开始使用 Flow
来注解类型,以便在构建时执行静态类型检查,并且我们发现,链式语法不适合做静态分析,因为几乎所有
jQuery 方法返回的结果都是相同的类型。我们当时之所以选择 Flow,是因为
@flow weak 模式等功能可以让我们逐步将类型应用于无类型的代码库上。

总而言之,移除 jQuery 意味着我们可以更多地依赖 Web 标准,让 MDN Web
文档成为前端开发人员事实上的默认文档,在将来可以维护更具弹性的代码,并且可以将
30KB 的依赖从我们的捆绑包中移除,加快页面的加载速度和 Java 的执行速度。

逐步解耦

虽然定下了最终目标,但我们也知道,分配所有资源一次性移除 jQuery
是不可行的。这种匆匆忙忙的做法可能会导致网站功能出现回归。相反,我们采取了以下的策略:

  1. 设定指标,跟踪整一行代码调用 jQuery
    的比率,并监控指标走势随时间变化的情况,确保它保持不变或下降,而不是上升。

澳门新葡萄京官网注册 8

  1. 我们不鼓励在任何新代码中导入 jQuery。为了方便自动化,我们创建了
    eslint-plugin-jquery(
    jQuery 功能,例如 $.ajax,CI 检查将会失败。

  2. 旧代码中存在大量违反 eslint 规则的情况,我们在代码注释中使用特定的
    eslint-disable
    规则进行了注解。看到这些代码的读者,他们都该知道,这些代码不符合我们当前的编码实践。

  3. 我们创建了一个拉请求机器人,当有人试图添加新的 eslint-disable
    规则时,会对拉取请求留下评论。这样我们就可以尽早参与代码评审,并提出替代方案。

  4. 很多旧代码使用了 pjax 和 facebox
    插件,所以我们在保持它们的接口几乎不变的同时,在内部使用 JS
    重新实现它们的逻辑。静态类型检查有助于提升我们进行重构的信心。

  5. 很多旧代码与 rails-behavior 发生交互,我们的 Ruby on Rails
    适配器几乎是“不显眼的”JS,它们将 AJAX 生命周期处理器附加到某些表单上:

// 旧方法 $(document).on(‘ajaxSuccess’, ‘form.js-widget’,
function(event, xhr, settings, data) { // 将响应数据插入到 DOM 中 })

  1. 我们选择触发假的 ajax*
    生命周期事件,并保持这些表单像以前一样异步提交内容,而不是立即重写所有调用,只是会在内部使用
    fetch()。

  2. 我们自己维护了 jQuery 的一个版本,每当发现我们不再需要 jQuery
    的某个模块的时候,就会将它从自定义版本中删除,并发布更轻量的版本。例如,在移除了
    jQuery 的 CSS 伪选择器之后(如:visible 或:checkbox)我们就可以移除
    Sizzle 模块了,当所有的 $.ajax 调用都被 fetch() 替换时,就可以移除 AJAX
    模块。

这样做有两个目的:加快 Java
执行速度,同时确保不会有新代码试图使用已移除的功能。

  1. 我们根据网站的分析结果尽快放弃对旧版本 Internet Explorer
    的支持。每当某个 IE 版本的使用率低于某个阈值时,我们就会停止向它提供
    Java 支持,并专注支持更现代的浏览器。尽早放弃对 IE 8 和 IE 9
    的支持对于我们来说意味着可以采用很多原生的浏览器功能,否则的话有些功能很难通过
    polyfill 来实现。

  2. 作为 GitHub.com
    前端功能开发新方法的一部分,我们专注于尽可能多地使用常规
    HTML,并且逐步添加 Java 行为作为渐进式增强。因此,那些使用 JS 增强的 Web
    表单和其他 UI 元素通常也可以在禁用 Java
    的浏览器上正常运行。在某些情况下,我们可以完全删除某些遗留的代码,而不需要使用
    JS 重写它们。

经过多年的努力,我们逐渐减少对 jQuery
的依赖,直到没有一行代码引用它为止。

自定义元素

近年来一直在炒作一项新技术,即自定义元素——浏览器原生的组件库,这意味着用户无需下载、解析和编译额外的字节。

从 2014 年开始,我们已经基于 v0
规范创建了一些自定义元素。然而,由于标准仍然在不断变化,我们并没有投入太多精力。直到
2017 年,Web Components v1 规范发布,并且 Chrome 和 Safari
实现了这一规范,我们才开始更广泛地采用自定义元素。

在移除 jQuery
期间,我们也在寻找用于提取自定义元素的模式。例如,我们将用于显示模态对话框的
facebox
转换为<details-dialog>元素(

我们的渐进式增强理念也延伸到了自定义元素上。这意味着我们将尽可能多地保留标记内容,然后再标记上添加行为。例如,<local-time>默认显示原始时间戳,它被升级成可以将时间转换为本地时区,而对于<details-dialog>,当它被嵌在
<details>元素中时,可以在不使用 Java
的情况下具备交互性,它被升级成具有辅助增强功能。

以下是实现<local-time>自定义元素的示例:

// local-time 根据用户的当前时区显示时间。//// 例如:// <local-time
datetime=”2018-09-06T08:22:49Z”>Sep 6, 2018</local-time>//class
LocalTimeElement extends HTMLElement { static get observedAttributes() {
return [‘datetime’] } attributeChangedCallback(attrName, oldValue,
newValue) { if (attrName === ‘datetime’) { const date = new
Date(newValue) this.textContent = date.toLocaleString() } }}if
(!window.customElements.get(‘local-time’)) { window.LocalTimeElement =
LocalTimeElement window.customElements.define(‘local-time’,
LocalTimeElement)}

我们很期待 Web 组件的 Shadow DOM。Shadow DOM 的强大功能为 Web
带来了很多可能性,但也让 polyfill 变得更加困难。因为使用 polyfill
会导致性能损失,因此在生产环境中使用它们是不可行的。

英文原文

)

责任编辑: