Firefox 78 新特性:DevTools 改进、全新正则表达式引擎以及丰富的 Web 平台更新

今天发布了全新的 Firefox 稳定版本,为 Web 开发者带来新功能。全新的正则表达式引擎、ECMAScript Intl API 的更新、新的 CSS 选择器、对 WebAssembly 的增强支持以及 Firefox 开发者工具的众多改进,等待您的体验。

本文仅提供了一些重点内容,如需了解所有细节,请查看以下链接

开发者工具改进

源映射变量,现已支持断点

通过我们对 最近 版本 的改进,使用源映射调试项目将比以往更可靠、更快。但是,我们还可以从源映射中挖掘出更多功能。您是否知道 Firefox 的调试器也可以将变量映射回它们原来的名称?这对于带有更改的变量名称和添加的辅助变量的 babel 编译代码特别有用。要使用此功能,请暂停执行并在调试器的“作用域”窗格中启用“映射”选项。

作为 DevTools 控制台和调试器两种功能的结合体,断点 使得将控制台日志添加到实时代码(或任何代码)变得更加容易 - 只要您将它们添加到工具箱中。Firefox 75 的新功能是,断点中的原始变量名称映射到编译后的作用域,因此引用将始终按预期工作。

Using variable mapping and logpoints in Debugger

要使作用域映射工作,请确保您的源映射 生成正确 并且包含足够的数据。在 Webpack 中,这意味着要避免使用“cheap”和“nosources”选项进行“devtools”配置。

Promise 和框架错误日志更详细

未捕获的 Promise 错误在现代异步 JavaScript 中至关重要,在 Angular 等框架中尤其如此。在 Firefox 78 中,您可以看到抛出的错误的所有详细信息正常显示,包括它们的名称和堆栈

Before/after comparison for improved error logs

此功能的实现仅通过 SpiderMonkey 工程团队和贡献者 Tom Schuster 之间的密切合作才得以实现。我们正在研究如何进一步改进错误日志记录,如果您有任何建议,请 告诉我们

监控失败的请求问题

失败或被阻止的网络请求有多种类型。例如,资源可能会被跟踪保护、附加组件、CSP/CORS 安全配置或不稳定的连接阻塞。一个健壮的 Web 尝试尽可能自动地优雅地从这些情况中恢复,而改进的网络监控可以帮助您调试它们。

Failed and blocked requests are annotated with additional reasons

Firefox 78 在网络面板中提供了详细的报告,用于报告被 增强跟踪保护附加组件CORS 阻塞的请求。

质量改进

检查器中更快的 DOM 导航

检查器现在打开和导航的速度比以前快得多,尤其是在具有大量 CSS 自定义属性 的网站上。过去,一些现代 CSS 框架受到速度减慢的影响。如果您遇到检查器速度不快的情况,请 报告性能问题。我们非常感谢您帮助报告性能问题,以便我们不断改进。

远程导航您的 Firefox for Android 以进行调试

远程调试 的新导航元素使您能够更无缝地使用即将发布的 Firefox for Android 新版本 测试您的移动内容。将手机通过 USB 连接并连接到标签页的远程调试后,您可以从桌面导航和刷新页面。

开发者版中的抢先体验 DevTools 功能

开发者版 是 Firefox 的预发布通道。您可以抢先体验工具和平台功能。它的设置默认情况下为开发者提供了更多功能。我们喜欢尽快将新功能带到开发者版以收集您的反馈,包括以下重点内容。

控制台和调试器中的异步堆栈

我们构建了新的功能来更好地支持控制台和调试器中的异步堆栈,用有关导致特定代码行执行的事件、计时器和 Promise 的信息扩展堆栈。我们一直在改进异步堆栈,基于使用 Firefox DevEdition 的开发者的早期反馈。在 Firefox 79 中,我们预计将在所有发布通道中启用此功能。

Async stacks add promise execution for both Console and Debugger

控制台显示失败的请求

具有 4xx/5xx 状态代码的网络请求现在默认情况下在控制台中记录为错误。为了便于理解,每个条目都可以展开以查看嵌入的网络详细信息。

Server responses with 4xx/5xx status responses logged in the Console

Web 平台更新

新的 CSS 选择器 :is 和 :where

在 78 版本中,Firefox 添加了对 :is():where() 伪类的支持,这些伪类允许您向浏览器提供一个选择器列表。然后,浏览器会将规则应用于与这些选择器中的 任何一个 匹配的 任何 元素。这对于在编写匹配大量不同元素的选择器时减少重复很有用。例如

header p, main p, footer p,
header ul, main ul, footer ul { … }

可以简化为

:is(header, main, footer) :is(p, ul) { … }

请注意,:is() 并不是什么新鲜事物 - 它在各种浏览器中已经支持了一段时间。有时它带有前缀和名称 any(例如 :-moz-any)。其他浏览器使用名称 :matches():is() 是 CSSWG 同意最终的标准名称。

:is():where() 基本上做的是同一件事,但有什么区别呢?嗯,:is() 会影响整个选择器的特指性,取其最特指参数的特指性。然而,:where() 的特指性值为 0 - 它是为了解决 :is() 影响特指性的问题而引入的。

如果您想使用 :is() 为一堆元素添加样式,但之后想使用简单选择器覆盖这些样式,该怎么办?您将无法做到,因为类选择器的特指性更高。在这种情况下,:where() 可以提供帮助。请查看我们的 :where() 示例,了解一个很好的说明。

使用 CSS :read-only 和 :read-write 样式化表单

到目前为止,HTML 表单已经有了大量的伪类,可以根据与输入的有效性相关的不同状态对其进行样式化 - 无论它们是必需的还是可选的,无论它们的数据是有效的还是无效的,等等。您可以在我们的 UI 伪类文章 中找到更多信息。

在此版本中,Firefox 启用了对 :read-only:read-write 的非前缀版本的支持。顾名思义,它们根据元素的内容是否可编辑来对其进行样式化

input:read-only, textarea:read-only {
  border: 0;
  box-shadow: none;
  background-color: white;
}

textarea:read-write {
  box-shadow: inset 1px 1px 3px #ccc;
  border-radius: 5px;
}

(注意:Firefox 已经支持这些带有 -moz- 前缀的伪类很长时间了。)

您应该注意,这些伪类并不局限于表单元素。您可以使用它们根据元素是否可编辑来对其进行样式化,例如设置或未设置 contenteditable<p> 元素

p:read-only {
  background-color: red;
  color: white;
}

p:read-write {
  background-color: lime;
}

新的正则表达式引擎

得益于 SpiderMonkey 中的正则表达式引擎,Firefox 现在支持 ECMAScript 2018 中引入的所有新的正则表达式功能,包括后顾 (正向和负向)、dotAll 标志、Unicode 属性转义和命名捕获组。

后顾和负向后顾 断言 使得能够查找被另一个模式 (或不被另一个模式) 紧接在前的模式。在本例中,负向后顾用于匹配仅当其前面没有减号时才匹配的数字。正向后顾将匹配前面没有减号的值。

'1 2 -3 0 -5'.match(/(?<!-)\d+/g);
// → Array [ "1", "2", "0" ]

'1 2 -3 0 -5'.match(/(?<=-)\d+/g);
// → Array [ "3", "5" ]

Unicode 属性转义\p{…}\{…} 的形式编写。例如,它们可用于匹配 Unicode 中的任何十进制数。这是一个支持 Unicode 的 \d 版本,它匹配任何 Unicode 十进制数,而不仅仅是 ASCII 数字 0-9。

const regex = /^\p{Decimal_Number}+$/u;

命名捕获组 允许您引用正则表达式匹配的字符串的特定部分,例如

let re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
let result = re.exec('2020-06-30');
console.log(result.groups);
// → { year: "2020", month: "06", day: "30" }

ECMAScript Intl API 更新

格式化列表的规则因语言而异。实现您自己的正确列表格式既不简单也不快。得益于新的 Intl.ListFormat API,JavaScript 引擎现在可以为您格式化列表。

const lf = new Intl.ListFormat('en');
lf.format(["apples", "pears", "bananas"]):
// → "apples, pears, and bananas"

const lfdis = new Intl.ListFormat('en', { type: 'disjunction' });
lfdis.format(["apples", "pears", "bananas"]):
// → "apples, pears, or bananas"

统一 NumberFormat 提案 中所定义的增强型语言敏感数字格式化现在已在 Firefox 中完全实现。请参阅 NumberFormat 构造函数 文档以了解可用的新选项。

ParentNode.replaceChildren

Firefox 现在支持 ParentNode.replaceChildren(),它用指定的新子节点集替换 Node 的现有子节点。这通常表示为 NodeList,例如由 Document.querySelectorAll() 返回的 NodeList

如果在没有参数的情况下调用 replaceChildren(),此方法提供了一种优雅的方式来清空节点中的子节点。它也是将节点从一个元素移到另一个元素的好方法。例如,在本例中,我们使用两个按钮将选定的选项从一个 <select> 框转移到另一个 <select> 框。

const noSelect = document.getElementById('no');
const yesSelect = document.getElementById('yes');
const noBtn = document.getElementById('to-no');
const yesBtn = document.getElementById('to-yes');
yesBtn.addEventListener('click', () => {
  const selectedTransferOptions = document.querySelectorAll('#no option:checked');
  const existingYesOptions = document.querySelectorAll('#yes option');
  yesSelect.replaceChildren(...selectedTransferOptions, ...existingYesOptions);
});

noBtn.addEventListener('click', () => {
  const selectedTransferOptions = document.querySelectorAll('#yes option:checked');
  const existingNoOptions = document.querySelectorAll('#no option');
  noSelect.replaceChildren(...selectedTransferOptions, ...existingNoOptions);
});

您可以在 ParentNode.replaceChildren() 中查看完整示例。

WebAssembly 多值支持

多值 是对核心 WebAssembly 的一项提议扩展,它使函数能够返回多个值,并使指令序列能够使用和生成多个堆栈值。文章 多值尽享 Wasm! 更详细地解释了这意味着什么。

WebAssembly 大整数支持

WebAssembly 现在支持使用 BigInt 从 JavaScript 导入和导出 64 位整数函数参数 (i64)。

WebExtensions

我们希望重点介绍本版本中对 WebExtensions API 的三个更改。

  • 使用 proxy.onRequest 时,现在正确应用了基于标签 ID 或窗口 ID 的限制过滤器。这对于希望在一个窗口中提供代理功能的附加组件很有用。
  • 从“所有标签”下拉菜单中 单击上下文菜单 现在将传递相应的标签对象。过去,错误地传递了活动标签。
  • 使用 downloads.download 以及 saveAs 选项时,现在会记住最近使用的目录。虽然此数据对开发者不可用,但对于用户来说非常方便。

TLS 1.0 和 1.1 移除

传输层安全 (TLS) 协议的版本 1.0 和 1.1 的支持已从 Firefox 78 和 Chrome 84 开始从所有浏览器中删除。阅读 TLS 1.0 和 1.1 移除更新 以了解之前的公告以及如果您受到影响需要采取的措施。

Firefox 78 是一个 ESR 版本

Firefox 遵循快速发布计划:每四周我们都会发布一个新版本的 Firefox。

除此之外,我们每年都会为企业用户提供一个新的 扩展支持版本 (ESR)。Firefox 78 ESR 包含自上一个 ESR (Firefox 68) 以来的所有增强功能,以及许多新功能,使您的企业部署更轻松。

值得注意的功能:在以前的 ESR 版本中,服务工作者 (以及 Push API) 被禁用。Firefox 78 是第一个支持它们的 ESR 版本。如果您的企业 Web 应用程序使用 AppCache 提供离线支持,您应尽快迁移到这些新 API,因为 AppCache 在 2021 年的下一个主要 ESR 中将不可用。

Firefox 78 是 OS X 10.9 Mavericks、OS X 10.10 Yosemite 和 OS X 10.11 El Capitan 的 macOS 用户支持的最后一个 Firefox 版本。这些用户将通过应用程序更新移至 Firefox ESR 频道。有关更多详细信息,请参阅 Mozilla 支持页面

另请参阅 Firefox for Enterprise 78 的发行说明

关于 Florian Scholz

Florian 是 MDN Web Docs 的内容负责人,撰写有关 Web 平台技术的文章并研究浏览器兼容性数据。他住在德国不来梅。

更多 Florian Scholz 的文章…

关于 Harald Kirschner (digitarald)

Harald “digitarald” Kirschner 是 Firefox 开发人员体验和工具的产品经理,他致力于赋能创作者编写、设计和维护一个对所有人开放且可访问的网络。在他在 Mozilla 的 8 年里,他在性能、Web API、移动设备、可安装的 Web 应用程序、数据可视化和开发人员推广项目中不断提升自己的技能。

更多 Harald Kirschner (digitarald) 的文章…