十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Gatsby 浏览器支持配置完全指南:Browserslist、Polyfill 自动注入与产物优化

Gatsby 浏览器支持配置完全指南:Browserslist、Polyfill 自动注入与产物优化 Gatsby 浏览器支持配置完全指南Browserslist、Polyfill 自动注入与产物优化【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址: https://gitcode.com/gh_mirrors/ga/gatsby本篇指南基于 Gatsby 官方文档 browser-support.md 展开深入讲解 Gatsby 的浏览器支持策略它默认支持哪些浏览器、Babel 如何自动注入 Polyfill、如何通过package.json中的browserslist字段自定义支持范围以及为什么只支持现代浏览器能显著减小打包体积。读完本文你将能够根据项目实际受众精确控制 Gatsby 的 JS/CSS 编译目标获得更小、更快的构建产物。Gatsby 默认支持哪些浏览器Gatsby 默认支持与当前稳定版 React.js 相同的浏览器集合即Edge、Firefox、Chrome、Safari 以及其它主流浏览器的最近版本。这意味着你不需要为旧版浏览器做额外的兼容性设计——Gatsby 的默认配置已经帮你处理了绝大多数场景。需要说明的是这里的默认支持并不是一个硬编码的浏览器名单而是由Browserslist 查询表达式推导出来的动态集合这一点在本文第三节会详细展开。Polyfill 自动注入Babel 与 core-js 的工作原理为什么需要 Polyfill新浏览器支持更多 JavaScript API而旧浏览器则缺少这些能力。例如Array.prototype.includes在较老的浏览器中并不存在。如果代码直接使用了这类新 API旧浏览器运行时会直接报错。Gatsby 利用Babel 的能力为你的目标浏览器自动添加所需的最小 Polyfill 集合。这一机制由babel/preset-env的useBuiltIns: usage模式驱动——它只会在代码中确实用到某个新 API、且目标浏览器不支持时才引入对应的core-jspolyfill 模块。以[].includes为例当你开始使用这个新 API 而某些目标浏览器不支持它时你无需手动处理兼容性问题Babel 会自动添加所需的 polyfillcore-js/modules/es7.array.includes。源码佐证babel-preset-gatsby 的实际配置在仓库的 packages/babel-preset-gatsby/src/index.js 中可以看到真实实现Gatsby 的 Babel 预设组合了babel/preset-env与babel/preset-react其中babel/preset-env的关键选项为[ resolve(babel/preset-env), { corejs: 3, // 使用 core-js 3 版本 loose: true, modules: stage test ? commonjs : false, useBuiltIns: usage, // 按需注入仅当代码使用且目标浏览器缺失时才引入 polyfill targets, // 浏览器目标来自 Browserslist 配置 exclude: [ // 排除会让代码整体变慢的 transform transform-typeof-symbol, transform-spread, proposal-nullish-coalescing-operator, proposal-optional-chaining, ...polyfillsToExclude, // 来自 gatsby-legacy-polyfills 的排除列表 ], }, ]其中targets的取值逻辑很关键babel-preset-gatsby/src/index.js在build-html、develop-html、test阶段目标被固定为{ node: current }服务端渲染与测试环境使用 Node.js 当前版本不针对浏览器其它浏览器相关阶段如build-javascript、develop目标则取自pluginBabelConfig.browserslist而这个值正是由你或 Gatsby 默认值的 Browserslist 配置计算而来。也就是说你配置的浏览器支持范围最终会直接决定 Babel 注入哪些 polyfill、保留哪些语法 transform。Polyfill 的按需注入链路从源码结构看polyfill 的注入还和打包入口的选择有关。在 packages/gatsby/src/utils/webpack.config.js 中getEntry()会根据hasES6ModuleSupport(directory)的返回值决定是否在入口中附加polyfill-entrycase build-javascript: return hasES6ModuleSupport(directory) ? { app: directoryPath(.cache/production-app), } : { polyfill: directoryPath(.cache/polyfill-entry), app: directoryPath(.cache/production-app), }当目标浏览器全部支持 ES6 Modules 时Gatsby 会跳过独立的 polyfill 入口从而避免不必要的兼容代码加载反之则注入 polyfill 入口以保障旧浏览器可用。同时webpack 的DefinePlugin中还会注入BROWSER_ESM_ONLY全局变量见webpack.config.js第 227 行供 Gatsby 运行时逻辑据此决策加载方式。使用 Browserslist 自定义支持的浏览器范围配置方式Gatsby 允许你通过声明package.json中的browserslist字段来自定义支持的浏览器版本列表。修改这些值会同时影响JavaScript 输出通过babel-preset-env的targets.browsers改变语法转换与 polyfill 注入策略CSS 输出通过autoprefixer改变需要添加厂商前缀的 CSS 属性。在仓库源码 packages/gatsby/src/utils/webpack-utils.ts 中可以看到 autoprefixer 的实际调用它使用overrideBrowserslist作为浏览器目标并将自己注册到 postcss 插件列表的最前面const autoprefixerPlugin autoprefixer({ overrideBrowserslist, flexbox: no-2009, // 不生成 2009 版旧 flexbox 前缀 ...(postCSSPlugins.find(p p.postcssPlugin autoprefixer)?.options ?? {}), }) postCSSPlugins.unshift(autoprefixerPlugin)Gatsby 的默认 Browserslist 配置Gatsby 默认模拟以下配置当前 Gatsby 5 时代{ browserslist: [0.25%, not dead and supports es6-module] }各查询条件的含义条件含义0.25%全球浏览器使用份额大于 0.25%not dead排除过去 24 个月内没有官方支持或更新的已死亡浏览器supports es6-module仅保留支持 ES6 Modulesscript typemodule的浏览器源码级验证默认值与回退逻辑在 packages/gatsby/src/utils/browserslist.ts 中getBrowsersList函数展示了完整的读取与回退逻辑const fallbackV1 [1%, last 2 versions, IE 9] let fallbackOthers [0.25%, not dead] if (_CFLAGS_.GATSBY_MAJOR 5) { fallbackOthers fallbackOthers.map( fallback fallback and supports es6-module ) } const fallback installedGatsbyVersion(directory) 1 ? fallbackV1 : fallbackOthers const config browserslist.loadConfig({ path: directory }) return config ?? fallback关键信息Gatsby 1.x 时代的默认值是1%,last 2 versions,IE 9即曾经明确支持 IE 9从 Gatsby 5 开始默认值升级为0.25%、not dead并追加了supports es6-module约束默认就不再支持 IE 11 等不支持 ES6 模块的浏览器只要你的项目配置了browserslist字段就会优先采用你的配置只有未配置时才使用上述默认值。对应的测试 packages/gatsby/src/utils/tests/browserslist.js 验证了这一行为getBrowsersList在loadConfig返回配置时直接返回用户配置返回undefined时则回退到默认值。此外该文件还导出了hasES6ModuleSupport(directory)它通过查询list , not supports es6-module是否为空来判断所有目标浏览器是否都支持 ES6 模块——这正是上一节所述 polyfill 入口是否注入的判断依据。实战建议只支持现代浏览器能带来什么收益原文档明确建议如果你只支持较新的浏览器请务必在package.json中显式声明这一点。这通常会带来两方面的直接收益更小的 JavaScript 文件Babel 不需要为旧浏览器生成兼容性 transform如将 class 转成 ES5 函数也不需要注入大量 polyfill产物体积显著下降更合理的运行时加载如前面源码所示当所有目标浏览器都支持 ES6 Modules 时Gatsby 会跳过独立的 polyfill 入口避免无用代码随页面加载。例如如果你确定自己的用户全部使用近两年内的 Chrome / Firefox / Safari / Edge可以配置{ browserslist: [ last 2 versions, not dead, not ie 11 ] }甚至更激进地只保留支持 ES6 模块的现代浏览器{ browserslist: [0.5%, not dead, supports es6-module] }反之如果你的站点有大量使用旧版浏览器的用户例如企业内部系统仍在使用 IE 11则应保留更宽泛的目标列表并接受由此带来的更大 polyfill 与编译产物。注意事项与验证方法配置位置唯一Gatsby 读取的是项目根目录package.json中的browserslist字段通过browserslist.loadConfig({ path: directory })解析见 browserslist.ts也可以使用 Browserslist 支持的其它标准配置来源如.browserslistrc文件。配置影响面广修改browserslist会同时影响 BabelJS 语法转换 polyfill与 autoprefixerCSS 厂商前缀改完配置后应重新执行gatsby build或gatsby develop并完整回归测试页面渲染与样式表现。验证生效情况可以通过观察构建产物体积变化来验证配置是否生效——收紧浏览器列表后build-javascript阶段的 JS 产物尤其 polyfill 部分应当明显减小也可以在浏览器开发者工具中检查是否还有多余的 polyfill 代码被加载。迁移提醒从旧版 Gatsby 升级时需注意默认浏览器列表的变化。相关讨论与迁移说明可参考 migrating-from-v4-to-v5.md 以及自定义配置系列的 babel.md后者对 Babel 层面的配置包括browserslist在 Babel 阶段的读取有更深入的说明。小结Gatsby 的浏览器支持不是黑盒它默认对齐 React 的现代浏览器基线通过 Babel core-js 按需注入 polyfill并把浏览器目标的控制权完整交给你——只需在package.json中声明browserslistJSbabel-preset-env与 CSSautoprefixer的编译产物便会同步调整。理解这一机制后你可以针对真实用户群体精准地收紧或放宽支持范围在兼容性与产物体积之间找到最适合自己项目的平衡点。【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址: https://gitcode.com/gh_mirrors/ga/gatsby创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表