当前位置: 首页 > article >正文

【关于 vite 使用plugin-legacy兼容低版本浏览器仍出现的问题的情况】

项目使用了vite+vue3+ts的方案,采用plugin-legacy+babel适配低版本浏览器

在开发工作中,项目使用了vite+vue3+ts的方案,但是需要适配低版本浏览器。首先使用了@vitejs/plugin-legacy插件,配置完成后发现并不能解决问题,
出现‘SyntaxError: Unexpected token .’的报错,如下图。刚开始下意识认为是低版本浏览器不兼容,便使用使用@vitejs/plugin-legacy进行降级处理。

在这里插入图片描述

但是打完包之后,第一次打开页面可以正常运行,但是在页面刷新后,却报错提示‘globalThis is not defined’,所以意识到可能哪里出现了问题。便对浏览器进行了是否支持es6进行检查,发现都可以支持。

1. 检查浏览器是否支持 ES6 模块

function isES6ModuleSupported() {
  try {
    // 尝试通过动态 import 检测模块支持
    new Function('import("")');
    return true;
  } catch (e) {
    return false;
  }
}

if (isES6ModuleSupported()) {
  console.log("浏览器支持 ES6 模块,应该能够运行 Vite 项目");
} else {
  console.log("浏览器不支持 ES6 模块,可能不支持 Vite");
}

2. 检查浏览器是否支持现代 JavaScript 特性

function checkModernJavaScriptSupport() {
  try {
    // 测试 `let` 和箭头函数支持
    let test = () => {};
    test();
    return true;
  } catch (e) {
    return false;
  }
}

if (checkModernJavaScriptSupport()) {
  console.log("浏览器支持现代 JavaScript 语法,应该支持 Vite");
} else {
  console.log("浏览器不支持现代 JavaScript 语法,可能不支持 Vite");
}


3. 检查 WebSocket 支持

function isWebSocketSupported() {
  return 'WebSocket' in window;
}

if (isWebSocketSupported()) {
  console.log("浏览器支持 WebSocket,应该能够支持 Vite 热更新");
} else {
  console.log("浏览器不支持 WebSocket,Vite 热更新可能无法正常工作");
}

所以重新看待SyntaxError: Unexpected token .这个报错,可以想到可选链操作符 (?.),所以在同样在index.html页面添加如下代码发现,出现报错。

const obj = { prop: { nestedProp: "Hello" } };
console.log(obj.prop?.nestedProp); // 可选链操作符(Optional chaining)

解决方案

但是已经用了@vitejs/plugin-legacy进行降级,所以怀疑可能某些地方可能并没有降级,所以采用babel进行针对性的降级,对@vitejs/plugin-legacy进行补充。

1、安装 Babel 相关插件

  • @vitejs/plugin-legacy:为旧版浏览器生成 ES5 兼容代码。

  • @babel/preset-env:根据目标浏览器转译代码。

  • @babel/plugin-proposal-optional-chaining:转译可选链操作符。

  • core-js:提供必要的 Polyfill,确保老旧浏览器支持最新 JavaScript 特性。

npm install --save-dev @vitejs/plugin-legacy @babel/core @babel/preset-env @babel/plugin-proposal-optional-chaining core-js

2、配置 Babel:在根目录新增babel.config.cjs文件

  • 让 Babel 专注于处理一些 @vitejs/plugin-legacy 无法覆盖的语法(如特殊插件或实验性语法)。

  • 避免在 Babel 中启用 @babel/preset-envuseBuiltIns: 'usage',以避免重复引入 Polyfill。


module.exports = {
  presets: [
    [
      '@babel/preset-env',
      {
        targets: false, // 不指定目标浏览器,由 plugin-legacy 管理
        useBuiltIns: false, // 不处理 Polyfill,由 plugin-legacy 管理
      },
    ],
  ],
  plugins: [
    '@babel/plugin-proposal-optional-chaining', // 支持可选链操作符
  ],
}

3、在入口文件中导入 Polyfill

你需要在项目的入口文件(如 main.tsindex.ts)中引入 core-jsregenerator-runtime,这样才能确保旧浏览器支持最新的 JavaScript 特性。

main.tsindex.ts 文件顶部添加:

import 'core-js/stable';
import 'regenerator-runtime/runtime'; // 如果你的代码使用了生成器(Generator),你也需要这个 Polyfill

4、配置 Vite 使用 @vitejs/plugin-legacy

通常 core-js 会在 @babel/preset-env 中自动处理,但是你也可以手动导入 Polyfill,确保代码在旧浏览器中能够正确执行。

在你的项目入口文件(如 main.tsindex.ts)中加入:

import { defineConfig } from 'vite';
import legacy from '@vitejs/plugin-legacy';

export default defineConfig({
    plugins: [
        legacy({
          targets: ['> 0.2%', 'not dead'],
          additionalLegacyPolyfills: [
            'core-js/stable',
            'regenerator-runtime/runtime',
          ], // 兼容 async/await
          }),
     ]
  }),

好了,大功告成,打包测试一下就OK


http://www.kler.cn/a/473267.html

相关文章:

  • WebSocket监听接口
  • 开放词汇检测新晋SOTA:地瓜机器人开源DOSOD实时检测算法
  • MFC读写文件实例
  • 《鸿蒙系统AI技术:筑牢复杂网络环境下的安全防线》
  • spring boot 集成 knife4j
  • KCP解读:C#库类图
  • 微信小程序实现长按录音,点击播放等功能,CSS实现语音录制动画效果
  • 庐山派k230使用串口通信发送数据驱动四个轮子并且实现摄像头画面识别目标检测功能
  • HCIE-day10-ISIS
  • 计算机视觉目标检测-DETR网络
  • Java-数据结构-链表-高频面试题(2)
  • Goldendb数据库dbtool命令介绍
  • web服务器架构,websocket
  • 使用高云小蜜蜂GW1N-2实现MIPI到LVDS(DVP)转换案例分享
  • Ollama + Openwebui 本地部署大型模型与交互式可视化聊天
  • 自动化脚本本地可执行但是Jenkins上各种报错怎么解决
  • Linux(上):基本知识篇
  • 常用的AT命令,用于查看不同类型的网络信息
  • SQLite 调试与性能优化指南
  • 去掉el-table中自带的边框线
  • 我的前端面试笔记(React篇)
  • NRF24L01模块STM32通信-通信初始化
  • js适配器模式
  • 《Spring Framework实战》3:概览
  • Hybrid A*算法-KinodynamicAstar::estimateHeuristic
  • LLM 大语言模型学习记录