1. 简介
Baseline 是一项计划,旨在更清晰地说明哪些 Web 功能是可互操作的,并且现在可以安全使用。得益于 Baseline 工具的进步,您现在可以直接在项目中将 Baseline 用作 Browserslist 查询,以便您的工具链可以根据您选择的 Baseline 目标更改代码的输出。
在本 Codelab 中,您将学习如何在示例项目中使用 Baseline,以及如何对其进行配置以选择特定的 Baseline 目标。您还将观察到项目工具链的输出如何根据您选择的 Baseline 目标而变化。
2. 在本地机器上设置演示
首先,前往您喜欢的终端应用,克隆演示代码库,然后进入项目目录:
git clone git@github.com:GoogleChromeLabs/baseline-demos.git
cd baseline-demos/tooling/webpack
此时,演示已集成 Baseline,但您需要检出一个从头开始的提交:
git checkout d3793f25
克隆代码库后,现在可以启动演示了。此项目使用 nvm 来管理 Node 版本控制。如果您全局安装了相当新的 Node 版本,则可能不需要完成此步骤,但如果您使用 nvm,请运行以下命令:
nvm install
nvm use
在此处,安装项目的软件包:
npm install
如果您想查看演示,请运行以下命令:
npm start
然后前往 http://localhost:8080。演示本身是一个卡片列表,可以使用页面顶部的表单字段进行过滤。应用本身使用了多种已达到 Baseline 阈值的功能。
完成演示后,前往终端并按 Ctrl+C,随时停止运行演示。
3. 如何将 Baseline 集成到项目中
此演示在开始时未指定 Browserslist 配置。Browserslist 是一种紧凑的查询语法,用于告知工具链必须支持的最低浏览器版本。例如,使用 a query of last 3 years 查询将指定广泛的目标。在此演示中,我们将指定与您可以在工具链中使用的 Baseline 目标一致的 Browserslist 查询。基线目标可以是以下项之一:
- 移动目标,它们会随着新浏览器的发布而随时间更新:
- Baseline 新近可用,它与从现在到 30 个月前这段时间内在核心浏览器组中实现的互操作功能保持一致。
- Baseline 广泛可用,它包括 30 个月或更长时间前在核心浏览器组中实现的互操作功能。
- 固定目标,它们表示固定时间点的浏览器版本。这些目标以 2016 年到当前年份之间的年份表示。
首先,我们将为项目选择移动的 Baseline 广泛可用目标。为此,请打开 package.json 并添加以下内容:
"browserslist": "baseline widely available"
4. 通过选择不同的 Baseline 目标来观察代码输出的变化
您刚刚选择了 Baseline 广泛可用作为演示项目的目标。接下来,您需要构建项目:
npm run build
由于项目的 babel.config.js 中将 @babel/preset-env 的 debug 选项指定为 true,因此会产生大量额外输出。首先,请注意捆绑器统计信息中 CSS 和 JavaScript 的大小:
assets by status 213 KiB [emitted]
asset js/home.5f3c5480.js 208 KiB [emitted] [immutable] [minimized] (name: home) 2 related assets
asset css/home.20db50ef.css 3.64 KiB [emitted] [immutable] (name: home) 1 related asset
asset index.html 564 bytes [emitted]
请注意,JavaScript 软件包为 208 KiB,CSS 为 3.64 KiB。这是因为此项目使用 core-js 进行 JavaScript Polyfill,并使用 autoprefixer 为尚未完全互操作的 CSS 属性应用特定于供应商的前缀。core-js 和 autoprefixer 都会受到所选 Baseline Browserslist 查询的影响。
输出中需要注意的另一件事是,您的 Baseline 广泛可用 Browserslist 查询如何转换为 Browserslist 查询。在您的项目中,它看起来类似于以下内容:
Using targets: {
"chrome": "108",
"edge": "108",
"firefox": "108",
"ios": "16",
"safari": "16"
}
请注意构建输出中由 core-js 注入的 Polyfill:
The corejs3 polyfill added the following polyfills:
es.iterator.constructor { "chrome":"108", "edge":"108", "firefox":"108", "ios":"16", "safari":"16" }
es.iterator.filter { "chrome":"108", "edge":"108", "firefox":"108", "ios":"16", "safari":"16" }
es.iterator.map { "chrome":"108", "edge":"108", "firefox":"108", "ios":"16", "safari":"16" }
如果您更改 Baseline 目标,此输出可能会发生变化。假设您的应用必须支持一组较旧的浏览器,因为 SLA 更加严格。如果是这种情况,您可能会选择更保守的目标。在 package.json 文件中,更改 Browserslist 配置以反映以下内容:
"browserslist": "baseline 2016"
这会选择 Baseline 2016 作为目标,并转换为 Browserslist 查询。重新运行构建后,您可以注意到工具链输出中的差异:
npm run build
首先,请注意捆绑器统计信息中项目 JavaScript 和 CSS 的文件大小变化:
assets by status 237 KiB [emitted]
asset js/home.b228612d.js 232 KiB [emitted] [immutable] [minimized] (name: home) 2 related assets
asset css/home.0c3e4fd7.css 3.91 KiB [emitted] [immutable] (name: home) 1 related asset
asset index.html 564 bytes [emitted]
您会注意到,JavaScript 软件包的大小增加了近 30 KiB。由于 autoprefixer 根据 2016 Baseline 目标添加了更多供应商前缀,因此项目的 CSS 仅略有增加。另请注意 Browserslist 查询的变化:
Using targets: {
"chrome": "53",
"edge": "14",
"firefox": "49",
"ios": "10",
"safari": "10"
}
与 Baseline 广泛可用目标相比,这些浏览器版本要早得多,以至于在这种情况下定位的 Edge 版本是 Chromium 之前的版本。
由 core-js 注入的 Polyfill 也会发生变化,这比选择 Baseline 广泛可用作为目标时要多得多:
The corejs3 polyfill added the following polyfills:
es.array.filter { "edge":"14" }
es.iterator.constructor { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
es.iterator.filter { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
es.object.to-string { "edge":"14", "firefox":"49" }
es.array.includes { "firefox":"49" }
es.string.includes { "edge":"14" }
es.array.map { "firefox":"49" }
es.iterator.map { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
es.symbol { "edge":"14", "firefox":"49" }
es.symbol.description { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
es.array.iterator { "chrome":"53", "edge":"14", "firefox":"49" }
web.dom-collections.iterator { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
es.array.push { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
es.regexp.to-string { "edge":"14" }
es.array.from { "edge":"14", "firefox":"49" }
es.regexp.exec { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
es.regexp.test { "edge":"14" }
es.error.cause { "chrome":"53", "edge":"14", "firefox":"49", "ios":"10", "safari":"10" }
这里的要点是,您的 Baseline 目标可能会对项目工具链转换应用的方式产生重大影响;此示例中的应用非常基本,无论是 React 还是应用本身,都没有太多尖端的开发者体验功能。对于复杂得多的应用,您可能会看到截然不同的结果,甚至可能需要添加更多 Polyfill、转换和其他来源的额外代码,以符合您选择的 Baseline 目标。
5. 定位下游浏览器
回顾一下,Baseline 目标的核心浏览器组包括以下浏览器:
- Chrome
- Android 上的 Chrome
- Firefox
- Android 上的 Firefox
- Edge
- macOS 上的 Safari
- iOS 上的 Safari
不过,您可以定位所谓的“下游浏览器”。这些浏览器的引擎源自核心浏览器组中的浏览器,最常见的是 Chromium。其中包括 Opera、Samsung Internet 等浏览器。除了核心浏览器组中的浏览器之外,您还可以通过将 with downstream 添加到任何有效的 Baseline Browserslist 查询来定位这些浏览器:
"browserslist": "baseline widely available with downstream"
这会根据 Baseline 广泛可用目标定位下游浏览器。如需了解如何将其解析为 Browserslist 查询,请重新构建项目:
npm start
然后注意 Browserslist 查询的变化:
Using targets: {
"android": "108",
"chrome": "108",
"edge": "108",
"firefox": "108",
"ios": "16",
"opera": "94",
"opera_mobile": "80",
"safari": "16",
"samsung": "21"
}
您还可以按年份定位下游浏览器。例如:
"browserslist": "baseline 2016 with downstream"
使用此配置,您的 Browserslist 查询将相应更改:
Using targets: {
"android": "53",
"chrome": "53",
"edge": "14",
"firefox": "49",
"ios": "10",
"opera": "40",
"opera_mobile": "80",
"safari": "10",
"samsung": "6.2"
}
6. Lint 工具和其他工具
Browserslist 中内置的 Baseline 查询对于捆绑器和工具链的其他部分等工具非常方便,但其他工具(例如 Lint 工具)也很有价值,这些工具已将 Baseline 目标作为其配置的一部分。
Lint 工具支持 Baseline 的一个很好的示例是 ESLint,它作为 CSS Lint 的一部分,提供 use-baseline 规则,使用 @eslint/css 让您可以定位 Baseline 新近可用、Baseline 广泛可用或 Baseline 年份。社区 @html-eslint/eslint-plugin 软件包中也有类似的规则,让您可以在 eslint.config.js 文件中对 HTML 功能执行相同的操作:
export default [
/* Omitted JS linting rules ... */
// Lint CSS files for Baseline:
{
files: ["**/*.css"],
plugins: {
css
},
language: "css/css",
rules: {
"css/no-duplicate-imports": "error",
// Lint CSS files to make sure they are using
// only Baseline Widely available features:
"css/use-baseline": ["warn", {
available: "widely"
}]
},
},
// Lint HTML and JSX files for Baseline:
{
files: ["**/*.html"],
...html.configs["flat/recommended"],
rules: {
// Lint HTML files to make sure they are using
// only Baseline Widely available features:
"@html-eslint/use-baseline": ["warn", {
available: "widely"
}]
}
}
];
此配置中有几点需要注意:
- HTML 和 CSS Lint 软件包都使用
use-baseline规则,并且使用available: "widely"配置选项将其设置为广泛可用。 - 对于这两个 Lint 软件包,Lint 违规的日志级别都设置为
"warn"。您可以将其设置为"error",以使用错误代码退出,防止构建发生。
您之前可能在运行 npm run build 时看到过 Lint 工具输出,但如需单独查看 Lint 工具输出,您可以运行以下命令:
npm run lint
您将看到的输出会突出显示项目 CSS 中的多个警告:
/var/www/baseline-demos/tooling/webpack-browserslist-config-baseline/src/css/normalize.css
222:3 warning Property 'outline' is not a widely available baseline feature css/use-baseline
/var/www/baseline-demos/tooling/webpack-browserslist-config-baseline/src/css/styles.css
62:3 warning Property 'outline' is not a widely available baseline feature css/use-baseline
81:23 warning Value 'subgrid' of property 'grid-template-rows' is not a widely available baseline feature css/use-baseline
7. 即将完成
在项目中使用 Browserslist 提供的 Baseline 查询确实需要了解一些底层构建工具和 Browserslist 本身,但将其放入项目本身的操作非常简洁。使用它的主要好处是,您不再需要考虑您支持的浏览器版本号,而是考虑为您完成繁重工作的 Baseline 目标。
此外,还有一个在 Rollup 上运行的演示版本,您也可以使用该演示来大致遵循本 Codelab。
Baseline 支持也开始出现在其他捆绑工具中。例如,Vite 在后台使用 Rollup,自版本 7 起,现在默认定位 Baseline 广泛可用浏览器。
无论您决定如何操作,将 Browserslist 中提供的 Baseline 查询引入您的项目,并选择适合您的 Baseline 目标,您都可以以更简单、更可靠的方式定位浏览器。