构建可在所有主流浏览器上顺畅运行的网站是 Google Cloud 的一项核心原则, 开放式网络生态系统不过,这意味着需要执行额外的工作,才能确保 您打算定位的每个浏览器都支持您编写的代码。如果您 想要使用新的 JavaScript 语言功能,您需要将这些 功能转换为向后兼容的格式,适用于尚不支持的浏览器 。
Babel 是编译代码时最常用的工具
包含新版语法的代码
(如 Node)能理解的对象。本指南假定您使用的是 Babel,
您需要按照设置说明操作
请将其添加到您的应用中(如果尚未添加)。选择“webpack
”
(如果您在 Build Systems
中将 webpack 用作模块打包器)。
要使用 Babel 仅转译用户需要的内容, 需要:
- 确定要定位的浏览器。
- 将
@babel/preset-env
与适当的浏览器目标搭配使用。 - 使用
<script type="module">
停止向不需要使用转译代码的浏览器发送转译代码。
确定您要定位的浏览器
在开始修改应用中代码的转译方式之前, 您需要确定哪些浏览器在访问您的应用。分析哪些浏览器 以及计划定位的用户 做出明智的决策。
使用 @babel/preset-env
转译代码通常会导致文件大于 原始形式。通过尽可能减少编译工作量 来减小网页包的大小,以提高网页性能。
无需添加特定插件即可选择性地编译某些语言 当前使用的许多功能,Babel 提供了许多预设,可将插件打包 。请使用 @babel/preset-env 以便仅包含您打算使用的浏览器所需的转换和 polyfill 定位条件。
在 Babel 的 presets
数组中包含 @babel/preset-env
.babelrc
:
{
"presets": [
[
"@babel/preset-env",
{
"targets": ">0.25%"
}
]
]
}
使用 targets
字段指定要涵盖的浏览器版本
向 browsers
字段添加适当的查询。@babel/preset-env
集成了 browserlist,一个在不同网页共用的开源配置,
用于定位浏览器的工具。如需查看兼容查询的完整列表,请参阅
browserslist 文档。
另一种方法是使用 .browserslistrc
文件列出环境
广告资源尺寸
">0.25%"
值指示 Babel 仅包含转换
需要支持占全球市场 0.25% 以上的浏览器
。这可确保您的 bundle 不包含不必要的转译
只有极少数用户使用的浏览器。
在大多数情况下,这比使用以下 配置:
"targets": "last 2 versions"
"last 2 versions"
值会将您的代码转译为
每个浏览器的最近两个版本,
这表示支持 Internet Explorer 等已停用的浏览器。
否则,这可能会使 app bundle 的大小不必要地增加
访问您的应用所需的资源。
最后,您应当选择合适的查询组合 定位符合您需求的浏览器。
启用新式 bug 修复
@babel/preset-env
将多个 JavaScript 语法功能分组到集合中并启用/停用
根据指定的目标浏览器来屏蔽它们。虽然这种方法效果很好,
语法功能会在目标浏览器包含只有一项功能的错误时进行转换。
这通常会导致转换的代码超出所需的范围。
此预设最初是作为单独的预设开发而成的,
@babel/preset-env
中的问题修复选项
通过将一些浏览器中已损坏的现代语法转换为最接近
同等语法,该语法在这些浏览器中未损坏。结果是几乎完全相同的现代代码
对语法进行了一些细微调整,以确保兼容所有目标浏览器。要使用此
请确保您已安装 @babel/preset-env
7.10 或更高版本,然后设置
将 bugfixes
属性设置为 true
:
{
"presets": [
[
"@babel/preset-env",
{
"bugfixes": true
}
]
]
}
在 Babel 8 中,bugfixes
选项默认处于启用状态。
使用 <script type="module">
JavaScript 模块(简称 ES 模块)是
所有主流浏览器。您可以使用模块
创建可以从其他模块导入和导出的脚本,
也可将其与 @babel/preset-env
一起使用,以仅定位支持的浏览器,
。
与其查询特定的浏览器版本或市场份额,不如考虑
在 .babelrc
文件的 targets
字段中指定 "esmodules" : true
。
{
"presets":[
[
"@babel/preset-env",
{
"targets":{
"esmodules": true
}
}
]
]
}
已支持许多使用 Babel 编译的更新的 ECMAScript 功能 在支持 JavaScript 模块的环境中。完成上述操作后 简化确保只使用转译代码的过程 。
支持模块的浏览器会忽略具有 nomodule
属性的脚本。
反之,不支持模块的浏览器会忽略带有
type="module"
。这意味着您可以添加一个模块以及一个已编译的回退。
理想情况下,包含应用的两个版本脚本,如下所示:
<script type="module" src="main.mjs"></script>
<script nomodule src="compiled.js" defer></script>
支持模块的浏览器会提取并执行 main.mjs
并忽略 compiled.js
。
不支持模块的浏览器则恰好相反。
如果您使用 webpack,可以在配置中为两个网站分别设置不同的目标 应用的不同版本:
- 仅适用于支持模块的浏览器的版本。
- 包含可在所有旧版浏览器中使用的已编译脚本的版本。此文件较大,因为转译需要支持更广泛的浏览器。
在此非常感谢 Connor Clark 和 Jason Miller 给出的评价。