兼容性问题

浏览器兼容性问题是什么?

浏览器兼容性问题通常是指网页或 Web 应用在不同浏览器或版本中表现不一致的问题。说白了无非就是 css不兼容JS Api在旧版本浏览器中不兼容。

解决思路

  1. 明白目标浏览器范围
  2. 找个插件将现代 JS 转到 ES5
  3. 处理一下CSS的兼容性问题

解决方案

  1. 通过定义 .browserslistrc 明确目标浏览器范围
  2. 使用 Babel 将现代 JS 转到 ES5
  3. 使用 Autoprefixer 给 CSS 加厂商前缀

好了,开搞

.browserslistrc文件是什么

.browserslistrc 文件是一个配置文件,用于定义目标浏览器和Node.js版本的兼容性列表。这个文件被多个前端工具链和库所使用,如Babel、Autoprefixer、ESLint等,可以帮助我们确定需要转译或添加兼容性前缀的JavaScript和CSS代码版本。通过配置 .browserslistrc,我们可以精确地控制代码应该兼容哪些浏览器和设备,从而优化构建输出和减少最终包的大小。

.browserslistrc文件中可以配置的内容

  • ‌浏览器名称和版本‌:例如,last 2 Chrome versions 表示最新的两个Chrome浏览器版本。
  • ‌市场份额‌:如 > 1% in US 表示在美国市场份额超过1%的浏览器。
  • ‌年份‌:since 2017 表示自2017年以来发布的所有浏览器版本。
  • ‌特定浏览器‌:not IE 11 表示不包括IE 11浏览器。

个人项目中使用.browserslistrc配置

在个人日常办公项目中 .browserslistrc 文件配置如下:

 1> 0.2%
 2last 2 versions
 3Firefox ESR
 4not dead
 5IE 11

这个配置的含义是:

  • 支持全球使用率超过0.2%的浏览器。
  • 支持最新的两个浏览器版本。
  • 支持Firefox的Extended Support Release(ESR)版本。
  • 排除所有已经不被官方支持(dead)的浏览器。
  • 额外包含IE 11浏览器,尽管它可能不在其他条件内

Babel是什么

Babel 是一个广泛使用的 JavaScript 编译器/转译器,其核心作用是将 高版本 JavaScript(如 ES6+)转换为向后兼容的低版本代码(如 ES5),以确保代码能在旧版浏览器或环境中正常运行。

Babel的主要作用

1. 语法转换(Syntax Transformation)

将现代 JavaScript 语法(如 let/const、箭头函数、类、模板字符串、解构赋值等)转换为等价的 ES5 语法,以便在不支持新特性的浏览器中运行。

2. Polyfill 填充新 API

通过插件(如 @babel/polyfill 或 core-js),为旧环境提供对新增全局对象(如 Promise, Array.from, Map, Set)的支持。

3. 按需转换(基于目标环境)

结合 .browserslistrc 配置,@babel/preset-env 可根据指定的目标浏览器自动决定哪些特性需要转换,哪些可以保留原样。

4. 支持 TypeScript 和 JSX

Babel 提供了对 TypeScript(通过 @babel/preset-typescript)和 React 的 JSX 语法(通过 @babel/preset-react)的解析与转换能力,无需依赖其他编译工具。

5. 插件化架构,高度可扩展

Babel 支持丰富的插件生态,开发者可以自定义语法转换规则,比如:

  • 按需引入 polyfill(@babel/plugin-transform-runtime)
  • 移除调试代码(@babel/plugin-transform-remove-console)
  • 支持装饰器、私有属性等实验性语法

@babel/preset-env的核心配置

@babel/preset-env 的参数项数量很多,但大部分我们都用不到。我们只需要重点掌握四个参数项即可:targets、useBuiltIns、modules 和 corejs。

@babel/preset-env 的 targets 参数

该参数项的写法和.browserslistrc 配置是一样的,主要是为了定义目标浏览器。如果我们对 targets 参数进行了设置,那么就不会使用 .browserslistrc 配置了,为了减少多余的配置,我们推荐使用 .browserslistrc 配置。

@babel/preset-env 的 useBuiltIns 参数

useBuiltIns 项取值可以是usageentryfalse。如果该项不进行设置,则取默认值 false

  • 设置成 false 的时候会把所有的 polyfill 都引入到代码中,整个体积会变得很大。
  • 设置成 entry 则是会根据目标环境引入所需的 polyfill,需要手动引入;
  • 设置成 usage 则是会根据目标环境和代码的实际使用来引入所需的 polyfill。 此处我们推荐使用:useBuiltIns: usage 的设置。

@babel/preset-env 的 corejs 参数

该参数项的取值可以是 2 或 3,没有设置的时候取默认值为 2。这个参数只有 useBuiltIns 参数为 usage 或者 entry 时才会生效。在新版本的Babel中,建议使用 core-js@3

@babel/preset-env 的 modules 参数

指定模块的输出方式,默认值是 "auto",也可以设置为 "commonjs""umd""systemjs" 等。

个人项目中使用Babel的配置

在个人日常办公项目中 .babel.config.js 文件配置如下:

 1module.exports = {
 2  plugins: [
 3    
 4    () => ({
 5      visitor: {
 6        MetaProperty(path) {
 7          path.replaceWithSourceString('process');
 8        },
 9      },
10    })
11  ],
12  presets: [
13    [
14      '@babel/preset-env', {
15        
16        useBuiltIns: "usage", 
17        corejs: 3
18      }
19    ],
20    '@babel/preset-typescript'
21  ],
22};
23

Autoprefixer 的使用

vite.config.ts文件中css的部分,添加 autoprefixer 的配置。

 1css: {
 2  postcss: {
 3    plugins: [
 4      postCssPxToRem({
 5        
 6        rootValue: 37.5,
 7        propList: ['*'],
 8      }),
 9      autoprefixer({
10        overrideBrowserslist: [
11          'Android 4.1',
12          'iOS 7.1',
13          'ff > 31',
14          'Chrome > 69',
15          'ie >= 8',
16          '> 1%'
17        ]
18      }),
19    ],
20  },
21},

总结

主要通过配置 .browserslistrc 明确目标浏览器范围,使用 Babel 将现代 JS 转到 ES5,主要用到的插件是 @babel/preset-env ,最后再使用 Autoprefixer 插件给 CSS 加厂商前缀。

个人笔记记录 2021 ~ 2025