Nuxt3兼容低版本浏览器

683 阅读2分钟

我们在开发前端项目时,最头疼和最需要考虑的一个问题就是浏览器兼容性问题。当我们兴致勃勃的将开发页面上线后,却发现很多用户还用着远古浏览器不舍的更新,然后弹出了错误页面时,这无疑是让人崩溃的。但是我也无法手动帮每一个用户去点击更新按钮,更何况有些用户不愿意去升级或更换浏览器。所以兼容低版本浏览器是非常有必要的,可以让你免于以下打扰:“前几天还可以用,怎么突然不行了......”,“我觉得你们应该考虑兼容这些非主流浏览器,而不是让我升级/更换浏览器......”,“你们这网站怎么回事,是不是技术不行?要不要找友商学习学习?......”

1.介绍

传统浏览器我们使用官方推荐的插件 @vitejs/plugin-legacy 来支持,它将自动生成传统版本的 chunk 及与其相对应 ES 语言特性方面的 polyfill。兼容版的 chunk 只会在不支持原生 ESM 的浏览器中进行按需加载。

2.引入依赖

yarn add -D @vitejs/plugin-legacy

# 必须安装 Terser,因为旧版插件使用 Terser 进行缩小。
yarn add -D terser

3.配置文件

// nuxt.config.ts
import legacy from '@vitejs/plugin-legacy'

export default defineNuxtConfig({
    vite: {
        build: {
            target: ['es2015', 'chrome78'],
        },
        plugins: [
            legacy({
                targets: ["chrome 78"],
                renderLegacyChunks: false,
                modernPolyfills: true
            })
        ]
    },
    hooks: {
        'build:manifest': (manifest) => {
            // vite polyfills 被错误地加载到最后,所以我们必须将它们移动到对象中的第一个位置。
            // 我们不能完全替换 `manifest`,因为这样我们只是改变了一个局部变量,而不是实际的 manifest
            // 这就是为什么我们必须改变引用的原因。
            // 由于 ES2015 对象字符串属性顺序或多或少是有保证的 - 顺序是按时间顺序排列的
            const polyfillKey = 'vite/legacy-polyfills'
            const polyfillEntry = manifest[polyfillKey]
            if (!polyfillEntry) return

            const oldManifest = { ...manifest }
            delete oldManifest[polyfillKey]

            for (const key in manifest) {
                delete manifest[key]
            }

            manifest[polyfillKey] = polyfillEntry
            for (const key in oldManifest) {
                manifest[key] = oldManifest[key]
            }
        }
    }
})

4.浅谈原理

我们观察打包后的文件会发现,插件为了兼容低版本浏览器会生成两套代码,一套是支持现代浏览器的高语法版本,一套是使用生成的带legacy标志的兼容旧版本浏览器的代码。