'ESlint - Error: Must use import to load ES Module

I am currently setting up a boilerplate with React, Typescript, styled components, webpack etc. and I am getting an error when trying to run eslint:

Error: Must use import to load ES Module

Here is a more verbose version of the error:

/Users/ben/Desktop/development projects/react-boilerplate-styled-context/src/api/api.ts
  0:0  error  Parsing error: Must use import to load ES Module: /Users/ben/Desktop/development projects/react-boilerplate-styled-context/node_modules/eslint/node_modules/eslint-scope/lib/definition.js
require() of ES modules is not supported.
require() of /Users/ben/Desktop/development projects/react-boilerplate-styled-context/node_modules/eslint/node_modules/eslint-scope/lib/definition.js from /Users/ben/Desktop/development projects/react-boilerplate-styled-context/node_modules/babel-eslint/lib/require-from-eslint.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename definition.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/ben/Desktop/development projects/react-boilerplate-styled-context/node_modules/eslint/node_modules/eslint-scope/package.json

The error occurs in every single one of my .js and .ts/ .tsx files where I only use import or the file doesn't even have an import at all. I understand what the error is saying but I have no idea why it is being thrown when in fact I only use imports or even no imports at all in some files.

Here is my package.json where I trigger the linter from using npm run lint:eslint:quiet:

{
  "name": "my-react-boilerplate",
  "version": "1.0.0",
  "description": "",
  "main": "index.tsx",
  "directories": {
    "test": "test"
  },
  "engines": {
    "node": ">=14.0.0"
  },
  "type": "module",
  "scripts": {
    "build": "webpack --config webpack.prod.js",
    "dev": "webpack serve --config webpack.dev.js",
    "lint": "npm run typecheck && npm run lint:css && npm run lint:eslint:quiet",
    "lint:css": "stylelint './src/**/*.{js,ts,tsx}'",
    "lint:eslint:quiet": "eslint --ext .ts,.tsx,.js,.jsx  ./src --no-error-on-unmatched-pattern --quiet",
    "lint:eslint": "eslint --ext .ts,.tsx,.js,.jsx  ./src --no-error-on-unmatched-pattern",
    "lint:eslint:fix": "eslint --ext .ts,.tsx,.js,.jsx  ./src --no-error-on-unmatched-pattern --quiet --fix",
    "test": "cross-env NODE_ENV=test jest --coverage",
    "test:watch": "cross-env NODE_ENV=test jest --watchAll",
    "typecheck": "tsc --noEmit",
    "precommit": "npm run lint"
  },
  "lint-staged": {
    "*.{ts,tsx,js,jsx}": [
      "npm run lint:eslint:fix",
      "git add --force"
    ],
    "*.{md,json}": [
      "prettier --write",
      "git add --force"
    ]
  },
  "husky": {
    "hooks": {
      "pre-commit": "npx lint-staged && npm run typecheck"
    }
  },
  "resolutions": {
    "styled-components": "^5"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.5.4",
    "@babel/plugin-proposal-class-properties": "^7.5.0",
    "@babel/preset-env": "^7.5.4",
    "@babel/preset-react": "^7.0.0",
    "@types/history": "^4.7.6",
    "@types/react": "^17.0.29",
    "@types/react-dom": "^17.0.9",
    "@types/react-router": "^5.1.17",
    "@types/react-router-dom": "^5.1.5",
    "@types/styled-components": "^5.1.15",
    "@typescript-eslint/eslint-plugin": "^5.0.0",
    "babel-cli": "^6.26.0",
    "babel-eslint": "^10.0.2",
    "babel-loader": "^8.0.0-beta.6",
    "babel-polyfill": "^6.26.0",
    "babel-preset-env": "^1.7.0",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-2": "^6.24.1",
    "clean-webpack-plugin": "^4.0.0",
    "dotenv-webpack": "^7.0.3",
    "error-overlay-webpack-plugin": "^1.0.0",
    "eslint": "^8.0.0",
    "eslint-config-airbnb": "^18.2.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-config-with-prettier": "^6.0.0",
    "eslint-plugin-compat": "^3.3.0",
    "eslint-plugin-import": "^2.25.2",
    "eslint-plugin-jsx-a11y": "^6.2.3",
    "eslint-plugin-prettier": "^4.0.0",
    "eslint-plugin-react": "^7.14.2",
    "eslint-plugin-react-hooks": "^4.2.0",
    "extract-text-webpack-plugin": "^3.0.2",
    "file-loader": "^6.2.0",
    "html-webpack-plugin": "^5.3.2",
    "husky": "^7.0.2",
    "prettier": "^2.4.1",
    "raw-loader": "^4.0.2",
    "style-loader": "^3.3.0",
    "stylelint": "^13.13.1",
    "stylelint-config-recommended": "^5.0.0",
    "stylelint-config-styled-components": "^0.1.1",
    "stylelint-processor-styled-components": "^1.10.0",
    "ts-loader": "^9.2.6",
    "tslint": "^6.1.3",
    "typescript": "^4.4.4",
    "url-loader": "^4.1.1",
    "webpack": "^5.58.2",
    "webpack-cli": "^4.2.0",
    "webpack-dev-server": "^4.3.1",
    "webpack-merge": "^5.3.0"
  },
  "dependencies": {
    "history": "^4.10.0",
    "process": "^0.11.10",
    "react": "^17.0.1",
    "react-dom": "^17.0.1",
    "react-router-dom": "^5.2.0",
    "styled-components": "^5.2.1"
  }
}

Here is my .eslintrc file:

{
  "extends": ["airbnb", "prettier"],
  "parser": "babel-eslint",
  "plugins": ["prettier", "@typescript-eslint"],
  "parserOptions": {
    "ecmaVersion": 8,
    "ecmaFeatures": {
      "experimentalObjectRestSpread": true,
      "impliedStrict": true,
      "classes": true
    }
  },
  "env": {
    "browser": true,
    "node": true,
    "jest": true
  },
  "rules": {
    "arrow-body-style": ["error", "as-needed"],
    "class-methods-use-this": 0,
    "react/jsx-filename-extension": 0,
    "global-require": 0,
    "react/destructuring-assignment": 0,
    "import/named": 2,
    "linebreak-style": 0,
    "import/no-dynamic-require": 0,
    "import/no-named-as-default": 0,
    "import/no-unresolved": 2,
    "import/prefer-default-export": 0,
    "semi": [2, "always"],
    "max-len": [
      "error",
      {
        "code": 80,
        "ignoreUrls": true,
        "ignoreComments": true,
        "ignoreStrings": true,
        "ignoreTemplateLiterals": true
      }
    ],
    "new-cap": [
      2,
      {
        "capIsNew": false,
        "newIsCap": true
      }
    ],
    "no-param-reassign": 0,
    "no-shadow": 0,
    "no-tabs": 2,
    "no-underscore-dangle": 0,
    "react/forbid-prop-types": [
      "error",
      {
        "forbid": ["any"]
      }
    ],
    "import/no-extraneous-dependencies": ["error", { "devDependencies": true }],
    "react/jsx-no-bind": [
      "error",
      {
        "ignoreRefs": true,
        "allowArrowFunctions": true,
        "allowBind": false
      }
    ],
    "react/no-unknown-property": [
      2,
      {
        "ignore": ["itemscope", "itemtype", "itemprop"]
      }
    ]
  }
}

And i'm not sure if relevant but also my tsconfig.eslint.json file:

{
  "extends": "./tsconfig.json",
  "include": ["./src/**/*.ts", "./src/**/*.tsx", "./src/**/*.js"],
  "exclude": ["node_modules/**", "build/**", "coverage/**"]
}

Not sure if anyone has come across this before? Googling the error does not present any useful forums or raised bugs, most of them just state not to use require in your files which I am not.



Solution 1:[1]

I think the problem is that you are trying to use the deprecated babel-eslint parser, last updated a year ago, which looks like it doesn't support ES6 modules. Updating to the latest parser seems to work, at least for simple linting.

So, do this:

  • In package.json, update the line "babel-eslint": "^10.0.2", to "@babel/eslint-parser": "^7.5.4",. This works with the code above but it may be better to use the latest version, which at the time of writing is 7.16.3.
  • Run npm i from a terminal/command prompt in the folder
  • In .eslintrc, update the parser line "parser": "babel-eslint", to "parser": "@babel/eslint-parser",
  • In .eslintrc, add "requireConfigFile": false, to the parserOptions section (underneath "ecmaVersion": 8,) (I needed this or babel was looking for config files I don't have)
  • Run the command to lint a file

Then, for me with just your two configuration files, the error goes away and I get appropriate linting errors.

Solution 2:[2]

This can happen with quite a lot of lately released frameworks like VueJS or Nuxt, mostly because of the usage of ESM modules (not fully or at all supported by older Node.js versions).

The fastest approach for this is to use something like nvm, after installing it, you could run:

  • nvm i 16 (v16 is the latest LTS as of time of writing)
  • nvm use 16

And you'll be running the project with a full ESM support.
You can double check that by running node -v.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 kissu