'Make "import/extensions" require the .js extension in a Node.js TypeScript project

First of all, some facts:

  • Node.js requires that all local imports include the imported module's extension (e.g. import hello from './hello.js', not import hello from './hello').
  • TypeScript will compile imports with or without the .js extension, which means a missing .js extension is a runtime error.
  • TypeScript doesn't transform imports to add the .js extension or convert .ts to .js.

In my Node.js project, I want to make missing a missing .js extension be a build-time error using the import/extensions ESLint rule. However, when I enable this rule using the following configuration:

{
  "root": true,
  "env": {
    "node": true
  },
  "parser": "@typescript-eslint/parser",
  "plugins": [
    "@typescript-eslint"
  ],
  "extends": [
    "eslint:recommended",
    "plugin:import/recommended",
    "plugin:import/typescript",
    "plugin:@typescript-eslint/eslint-recommended",
    "plugin:@typescript-eslint/recommended"
  ],
  "settings": {
    "import/resolver": {
      "typescript": {},
      "node": {
        "extensions": [".js"]
      }
    }
  },
  "rules": {
    "import/extensions": ["error", "ignorePackages"]
  }
}

running eslint gives me the following error:

/sandbox/src/index.ts
  1:19  error  Missing file extension "ts" for "./hello.js"  import/extensions

Source files:

// index.ts
import hello from "./hello.js";

hello();
// hello.ts
export default function hello() {
  console.log("Hello");
}

CodeSandbox link: https://codesandbox.io/s/elated-germain-13glp7



Solution 1:[1]

I fixed this with the following config:

{
  "root": true,
  "env": {
    "node": true
  },
  "extends": [
    "eslint:recommended",
    "plugin:import/recommended",
    "plugin:import/typescript",
    "plugin:@typescript-eslint/eslint-recommended",
    "plugin:@typescript-eslint/recommended"
  ],
  "rules": {
    "import/extensions": ["error", "ignorePackages"],
    "import/no-unresolved": "off"
  }
}

The main thing is to disable the "import/no-unresolved" rule and remove "settings"."import/resolver"."node". ("import/no-unresolved" is redundant as unresolved imports are resolved at the compilation stage.) Other items removed here were already being added as a result of extending the @typescript-eslint plugins.

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 Steve