Skip to content

Latest commit

 

History

History
142 lines (117 loc) · 17.4 KB

compat.md

File metadata and controls

142 lines (117 loc) · 17.4 KB

浏览器兼容性

😂 当你面对低版本浏览器报错时,会不会感觉 丈二的和尚摸不着头脑?如果你没有这样的困惑,那你可能不需要看这篇文章,因为你已经可以游刃有余的去处理这些问题了。

为什么报错?

😎 浏览器高版本运行时正常,低版本运行时就报错,其根本原因源自你 使用了最新的 Javascript 特性

三大原则

对浏览器进行降级兼容从技术层面上来说这是不可取的,但是从一个产品来说它又是必需的,为此你应当遵循以下三大原则:

1. 尽量不使用新增的扩展方法
方法 最低支持 替代方法
String.includes() Edge String.indexOf()
String.fromCodePoint() Edge String.fromCharCode()
String.codePointAt() Edge String.charCodeAt()
String.startsWith() Edge String.substring()
String.endsWith() Edge String.substring()
String.normalize() Edge
String.padStart() Edge Polyfill
String.padEnd() Edge Polyfill
String.repeat() Edge Polyfill
String.matchAll() Edge Regex
String.trimStart() Edge String.replace(/^\s+/g, '')
String.trimEnd() Edge String.replace(/\s+$/g, '')
String.raw() Edge Polyfill
Number.isFinite() Edge Polyfill
Number.isNaN() Edge Polyfill
Number.parseInt() Edge parseInt
Number.parseFloat() Edge parseFloat
Number.isInteger() Edge Polyfill
Number.EPSILON() Edge Math.pow(2, -52)
Number.isSafeInteger() Edge Polyfill
Math.trunc() Edge Polyfill
Math.sign() Edge Polyfill
Math.cbrt() Edge Polyfill
Math.clz32() Edge Polyfill
Math.imul() Edge Polyfill
Math.fround() Edge Polyfill
Math.hypot() Edge Polyfill
Math.expm1() Edge Polyfill
Math.log1p() Edge Polyfill
Math.log10() Edge Polyfill
Math.log2() Edge Polyfill
Math.sinh() Edge Polyfill
Math.cosh() Edge Polyfill
Math.cosh() Edge Polyfill
Math.tanh() Edge Polyfill
Math.asinh() Edge Polyfill
Math.acosh() Edge Polyfill
Math.atanh() Edge Polyfill
Array.from() Edge Polyfill
Array.of() Edge Array.slice()
Array.copyWithin() Edge Polyfill
Array.find() Edge Polyfill
Array.findIndex() Edge Polyfill
Array.fill() Edge Polyfill
Array.entries() Edge Polyfill
Array.keys() Edge Polyfill
Array.values() Edge Polyfill
Array.includes() Edge Polyfill
Array.flat() Edge Polyfill
Array.flatMap() Edge Polyfill
Object.is() Edge Polyfill
Object.assign() Edge Polyfill
Object.getOwnPropertyDescriptors() Edge Polyfill
Object.setPrototypeOf() IE11 Polyfill
Object.values() Edge Polyfill
Object.entries() Edge Polyfill
Object.fromEntries() Edge Polyfill

2. 安装第三方库时应优先选择兼容运行环境的版本
包名 最低支持 polyfills
react-dom@>=16.0.0 IE9+ MapSet
react-intl@>=4.0.0 IE11+ Intl
@loadable/components IE9+ Map、Set

3. 记录项目所需 Polyfill
俗话说:好记性不如烂笔头,养成良好的笔记习惯,可以让你游刃有余的去处理浏览器的兼容性问题

解决方案

为了支持新语法,我们会使用 babel 来编译 Javascript,但是 babel 不会编译运行时的扩展,例如 PromiseMap 等等。这些需要我们通过 Polyfill 解决,通常有以下两个方案解决:

  1. 构建时:core-jsregenerator-runtime
  2. 运行时:polyfill.ioalicnd 推荐

构建时

通过搭配 @babel/preset-env 来使用,它会将所有所需的运行时扩展打包,这种方式不取决于浏览器环境,所以通常我们会获得臃肿的 polyfill 代码。

运行时

它会根据浏览器环境动态返回所需的 polyfill 代码,这意味着你可以按需加载,从而减少不必要的 polyfill 代码打包。受益的同时,你还需要承担第三方服务器带来的延迟或宕机的风险。幸运的是这种风险只会影响低版本浏览器的受众,因为对于高版本浏览器来说它不需要任何的 polyfill 就能正常的运行起来。

如何去做?

🥳 为了解决 使用 Javascript 新特性 所带来的运行时报错,脚手架通过引入 eslint-plugin-compat 插件为你自动检测 Javascript 代码的浏览器兼容性,所以,你只需要在项目的 package.json 中定义好 browserslist 配置即可,具体示例如下:

{
  ...
  "browserslist": [
    "> 0.5%",
    "last 2 versions",
    "Firefox ESR",
    "not dead",
    "ie > 10"
  ],
  ...
}

有时候,你还可能想在项目中使用最新的 Javascript 特性,然后在运行时提供 polyfill,那么,你只需要将 polyfill 记录在 .eslintrc 文件中的 settings 字段下的 polyfills 字段内即可,示例如下:

{
  ...
  "settings": {
    "polyfills": ["Promise"]
  },
  ...
}

最后,由于每个项目所依赖的第三库以及扩展方法是不同的,所以无法一一去列举步骤,你只要遵循 三大原则 并了解所需的 polyfill,然后使用 运行时 去完成 polyfill 的引入即可。