Skip to content

ESLint "Must use import to load ES Module" 错误

问题描述

当在 React + TypeScript + Webpack 项目中使用 ESLint 时,可能会遇到以下错误:

Error: Must use import to load ES Module

详细的错误信息通常类似于:

Parsing error: Must use import to load ES Module
require() of ES modules is not supported.
Instead rename definition.js to end in .cjs, change the requiring code to use import(), 
or remove "type": "module" from package.json

这个错误通常出现在 .js.ts.tsx 文件中,即使这些文件只使用了 import 语句或根本没有导入语句。

问题根源

这个问题的根本原因是 ESLint 解析器与项目模块系统的兼容性问题。当项目 package.json 中设置了 "type": "module" 时,Node.js 会将所有 .js 文件视为 ES 模块,但旧版的 ESLint 解析器(如 babel-eslint)可能无法正确处理这种情况。

解决方案

方案一:更新 Babel 解析器(推荐)

这是最常见且最有效的解决方案。将已废弃的 babel-eslint 替换为官方维护的 @babel/eslint-parser

  1. 安装新解析器
bash
npm uninstall babel-eslint
npm install @babel/eslint-parser @babel/core --save-dev
  1. 修改 ESLint 配置
json
{
  "parser": "@babel/eslint-parser",
  "parserOptions": {
    "requireConfigFile": false,
    "ecmaVersion": "latest",
    "sourceType": "module",
    "babelOptions": {
      "presets": ["@babel/preset-env"]
    }
  }
}

TIP

如果使用 React,还需要添加 @babel/preset-react 到 babelOptions.presets 中

方案二:修改 ESLint 配置文件扩展名

如果使用 JavaScript 配置文件,可以将其扩展名改为 .cjs

bash
mv .eslintrc.js .eslintrc.cjs

或者使用 JSON 格式的配置文件:

bash
mv .eslintrc.js .eslintrc.json

方案三:更新 Node.js 版本

确保使用较新版本的 Node.js(v14 或更高版本),这些版本对 ES 模块有更好的支持:

bash
# 使用 nvm 管理 Node.js 版本
nvm install 16
nvm use 16

方案四:检查相关依赖

确保所有相关依赖都已正确安装:

bash
# 清除并重新安装依赖
rm -rf node_modules package-lock.json
npm install

方案五:VSCode 用户

如果你使用 VSCode 并且安装了 ESLint 扩展,尝试以下步骤:

  1. 禁用 ESLint 扩展
  2. 重启 VSCode
  3. 重新启用 ESLint 扩展

配置示例

以下是修复后的完整 ESLint 配置示例:

json
{
  "extends": ["airbnb", "prettier"],
  "parser": "@babel/eslint-parser",
  "plugins": ["prettier", "@typescript-eslint"],
  "parserOptions": {
    "ecmaVersion": "latest",
    "sourceType": "module",
    "requireConfigFile": false,
    "babelOptions": {
      "presets": ["@babel/preset-env", "@babel/preset-react"],
      "plugins": ["@babel/plugin-proposal-class-properties"]
    }
  },
  "env": {
    "browser": true,
    "node": true,
    "jest": true
  },
  "rules": {
    // 你的规则配置
  }
}
javascript
module.exports = {
  extends: ["airbnb", "prettier"],
  parser: "@babel/eslint-parser",
  plugins: ["prettier", "@typescript-eslint"],
  parserOptions: {
    ecmaVersion: "latest",
    sourceType: "module",
    requireConfigFile: false,
    babelOptions: {
      presets: ["@babel/preset-env", "@babel/preset-react"],
      plugins: ["@babel/plugin-proposal-class-properties"]
    }
  },
  env: {
    browser: true,
    node: true,
    jest: true
  },
  rules: {
    // 你的规则配置
  }
};

常见问题排查

  1. 确保 @babel/core 已安装

    bash
    npm list @babel/core
  2. 检查 Node.js 版本

    bash
    node -v
  3. 验证 package.json 配置: 确保没有冲突的模块类型声明

  4. 检查所有相关依赖: 特别是与 Babel 和 ESLint 相关的包需要保持版本兼容

总结

ESLint 的 "Must use import to load ES Module" 错误通常是由于使用已废弃的 babel-eslint 解析器与 ES 模块系统不兼容导致的。通过更新到 @babel/eslint-parser 并正确配置,可以解决这个问题。

WARNING

如果项目中使用 TypeScript,考虑使用 @typescript-eslint/parser 作为替代方案,它可能提供更好的 TypeScript 支持。

保持开发工具链的更新是避免这类问题的最佳实践。定期检查并更新 ESLint、Babel 和相关依赖的版本,可以确保项目的长期稳定性。