如何兼容低版本chrome谷歌浏览器

1,741 阅读3分钟

兼容低版本chrome谷歌浏览器

前言

在chrome内核较高的浏览器上面可以浏览的代码,有可能在chrome内核较低的浏览器中会出现白屏、转圈等一系列问题,所以需要针对chrome内核较低的浏览器做出兼容处理。

举例项目环境配置

"vite": "^4.5.0"
"vue": "^3.3.6"

报错与解决办法

语法报错

当在控制台看到了这个报错的时候不要惊慌:

Uncaught SyntaxError: Unexpected token ?

image.png

这个搜索一下就能发现指的是:空值合并运算符的问题.

与他相似的还有

SyntaxError: Unexpected token xxx等等。

这一类的问题都是语法太过新颖,导致浏览器解析不了

这一类的解决办法一般都是在打包的时候做一层转义,也就是通俗意义上的降低es版本(es2015最有用的一次)。

  //vite.config.ts
  export default defineConfig({
    build: {
      // ...
      target: 'es2015',
      // ...
    },
  })

缺少API

这一类的报错是经常能够看见的,报错格式都是相似的,例如:

Uncaught ReferenceError: xxx is not defined

这种就是存在着无法解析的api,也可以说是缺少了api。

这种一般需要给依赖打一个补丁或者自己寻找一下是否没有安装依赖。

安装依赖的办法就不讲解了,来讲一下如何打补丁:

如何官方的打补丁

首先需要寻找官方的polyfill

如当前配置的框架是vue的,那就是这个地址@vitejs/plugin-legacy

image.png

从划线部分可以得知,这个插件就是为了支持因为各种原因不支持新功能的浏览器。

之后跟随着教程

npm i @vitejs/plugin-legacy
// vite.config.js
import legacy from '@vitejs/plugin-legacy'

export default {
  plugins: [
    legacy({
      targets: ['defaults', 'not IE 11'],
    }),
  ],
}

其中教程中有给了几个OPTIONS

      legacy({
        targets: ['Chrome 61'], 
        modernPolyfills: ['es.global-this', 'es.array.at', 'web.queue-microtask', 'esnext.set.intersection'],
        renderLegacyChunks: false,
      }),

targets:指定了要兼容的最低浏览器版本是 Chrome 61

modernPolyfills: 指定安装一些补丁,可以针对性挑选。

renderLegacyChunks: 这个选项设置为 false,表示只会生成一个能够兼容所有版本的代码。(但是注意可能会导致新版本的浏览器加载一些不需要的补丁。)

如何自己打补丁

举一个例子:解决浏览器端 globalThis is not defined 报错

如上讲解,就是缺少了这个依赖或者无法解析。

Q:那应该怎么处理呢?

A:如下操作:

<body>
   /...
  <script>
    this.globalThis || (this.globalThis = this)
  </script>
</body>

这个问题除去手动打补丁

当然也是有可以安装的依赖补丁的

 npm i globalthis/auto

然后引入即可,一把抓住即刻炼化。

//main.ts
import 'globalthis/auto'

API兼容问题

IntersectionObserver 问题

举一个例子,在控制台看到了那么一个报错:

TypeError: Failed to construct 'IntersectionObserver': member root is not of type Element.

image.png

从报错上看 抓住关键词是 not of type Element,可以从这一方面下手。

image.png

从内置的类型中可以看出,第二个参数支持的为options?: IntersectionObserverInit | undefined ,点进去观察可得参数root支持的是 Element | Document | null等。

Q:那为什么会报错呢?

A:问题就在于老版本的api,老版本的api第二个参数支持的root类型一定是必须是 Element,这就导致了一部分第三方库的Document类型没有办法在低版本的浏览器上面使用,就会报这个错误。

Q:那如何解决这个报错呢?

A:可以根据项目具体的情况,对老版本的API做处理,使他进行适配:

class IntersectionObserverLegacy extends IntersectionObserver {
  constructor (...args) {
    
    const opts = args[1]
    const root = opts?.root
    if (root === document) {
      opts.root = document.body
    }
    super(...args)
  }
}
window.IntersectionObserver = IntersectionObserverLegacy

结语

以上便是答主遇到过并且解决了的问题以及携带解决的步骤。

遇到了问题先不要烦躁焦虑,最主要的还是耐心,这一类的问题有些可以在网上找到解决办法,有些只有零零散散的信息可以按图索骥,也有一些网上也检索不到一丝一毫的消息,这个时候就需要一点点的排查,一点点的试验,一点点的调整。

每一次失败都是为成功积累。

共勉。