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