普通网友 2025-11-05 07:55 采纳率: 98.6%
浏览 5
已采纳

Vue3项目中使用require报错:Uncaught ReferenceError

在Vue3项目中使用`require`时报错“Uncaught ReferenceError: require is not defined”,主要原因在于Vue3默认采用Vite或Webpack 5构建,而这两者在ESM(ECMAScript模块)环境下不支持CommonJS的`require`语法。该问题常见于尝试动态引入本地资源或第三方库时。由于浏览器原生不支持`require`,且Vite默认以ESM方式运行,导致运行时找不到`require`函数。解决方案包括:改用`import()`动态导入、配置Vite支持CommonJS(不推荐),或通过条件判断适配环境。建议遵循ESM标准,避免在前端代码中使用`require`。
  • 写回答

1条回答 默认 最新

  • 高级鱼 2025-11-05 09:05
    关注

    1. 问题背景与常见场景

    在现代前端开发中,Vue3项目普遍采用 Vite 或 Webpack 5 作为构建工具。这些工具默认启用 ESM(ECMAScript Module) 模块系统,以提升打包效率和开发体验。然而,许多开发者在迁移旧项目或集成第三方库时,仍习惯使用 Node.js 中常见的 require 语法,例如:

    const utils = require('./utils')

    当此类代码运行于浏览器环境时,会抛出错误:Uncaught ReferenceError: require is not defined。这是因为浏览器本身并不支持 CommonJS 的 require 函数,且 Vite 和 Webpack 5 在 ESM 模式下不再自动注入该变量。

    构建工具模块规范是否支持 require典型错误表现
    ViteESM 优先❌ 不支持require is not defined
    Webpack 5混合模式(可配置)⚠️ 需显式启用运行时报错或警告
    Webpack 4CommonJS 兼容✅ 支持无此问题

    2. 根本原因分析

    从技术演进角度看,require 是 CommonJS 规范的核心函数,最初设计用于服务端 JavaScript(如 Node.js),其执行是同步的,依赖文件系统路径解析机制。而 ESM 是浏览器原生支持的模块标准,采用静态分析、异步加载,语义更清晰、性能更优。

    Vite 基于原生 ES 模块(通过 import 动态导入)实现极速热更新,因此完全剥离了对 CommonJS 的运行时支持。即使某些库导出了 CommonJS 格式,Vite 也会在构建阶段将其转换为 ESM。

    以下情况容易触发该问题:

    • 动态引入本地 JSON 文件:require(`./locales/${lang}.json`)
    • 条件加载组件:if (env === 'dev') require('./mockService')
    • 使用 Node.js 内置模块(如 fs, path
    • 集成未适配 ESM 的第三方库
    graph TD A[开发者使用 require] --> B{构建工具类型} B -->|Vite / Webpack 5| C[ESM 环境] C --> D[浏览器不识别 require] D --> E[报错: require is not defined] B -->|旧版 Webpack| F[支持 CommonJS] F --> G[正常运行]

    3. 解决方案详解

    针对不同使用场景,推荐如下解决方案:

    1. 使用 import() 实现动态导入:适用于按需加载模块或动态路径引入。
    2. 预处理资源文件:将 JSON 等静态资源通过 import 静态引入或使用 import.meta.glob 批量注册。
    3. 配置 Webpack 5 兼容层(仅限 Webpack):通过 configureWebpack 启用 node: { global: true, __filename: true, __dirname: true }
    4. 环境判断 + 条件导入:区分客户端与服务端逻辑,避免在浏览器中执行 require
    5. 替换为 ESM 友好型库:优先选择已发布 ESM 版本的第三方包。
    // ✅ 推荐:使用 import() 替代 require()
    async function loadLocale(lang: string) {
      const module = await import(`../locales/${lang}.json`)
      return module.default
    }
    
    // ✅ 使用 import.meta.glob 处理多文件
    const modules = import.meta.glob('../components/**/*.vue')
    Object.keys(modules).forEach(path => {
      router.addRoute(createRouteFromPath(path, modules[path]))
    })
    

    对于必须保留 require 的遗留代码,可通过定义空桩(shim)防止崩溃:

    if (typeof require === 'undefined') {
      globalThis.require = (id) => {
        console.warn(`require("${id}") is not supported in browser`)
        return null
      }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

问题事件

  • 已采纳回答 11月6日
  • 创建了问题 11月5日