Skip to content

Latest commit

 

History

History
210 lines (149 loc) · 9.43 KB

File metadata and controls

210 lines (149 loc) · 9.43 KB
  • Repo: eslint/eslint
  • Start Date: 2024-03-09
  • RFC PR: #117
  • Authors: Arya Emami

Add Support for TypeScript Config Files

Summary

Add support for TypeScript config files (eslint.config.ts, eslint.config.mts, eslint.config.cts)

Motivation

The primary motivation for adding support for TypeScript configuration files to ESLint is to enhance the developer experience and accommodate the evolving JavaScript ecosystem. As TypeScript's popularity continues to grow, more projects are adopting TypeScript not only for their source code but also for their configuration files. This shift is driven by TypeScript's ability to provide compile-time type checks and IntelliSense. By supporting eslint.config.ts, eslint.config.mts, and eslint.config.cts, ESLint will offer first-class support to TypeScript users, allowing them to leverage these benefits directly within their ESLint configuration.

Detailed Design

The goal is to seamlessly support TypeScript configuration files in ESLint. To achieve this, ESLint will need to recognize and parse TypeScript configuration files in the same way it does for JavaScript configuration files. This will involve creating the configuration file resolution logic to recognize .ts, .mts, and .cts files as valid ESLint configuration files. We will need to treat eslint.config.mts files as ECMAScript Modules (ESM) and eslint.config.cts files as CommonJS (CJS). The module resolution for eslint.config.ts files will depend on the type field in the nearest package.json. The maintainers of ESLint have raised some valid concerns some of which include:

  • There should not be extra overhead for JavaScript users. This means this change should not have a significant impact (if any at all) affecting users who use plain JavaScript config files.
  • The external tools that are used to parse the config files written in TypeScript should not create side effects. Specifically, it is imperative that these tools do not interfere with Node.js's native module resolution system by hooking into or altering the standard import/require mechanisms. This means tools like ts-node and tsx might not be suitable for this purpose.

So far the tool that seems to be the most suitable for this purpose is jiti. It does not introduce side effects and performs well, demonstrating its reliability. It also seems to be more battle-tested given some established frameworks such as Nuxt and Tailwind CSS have been using it to load their configuration files.

Examples

with eslint.config.mts file:

import eslint from "@eslint/js"
import type { Linter } from "eslint"

const config: Linter.FlatConfig[] = [
  eslint.configs.recommended,
  {
    rules: {
      "no-console": [0],
    },
  },
]

export default config

with eslint.config.cts file:

import type { Linter } from "eslint"
const eslint = require("@eslint/js")

const config: Linter.FlatConfig[] = [
  eslint.configs.recommended,
  {
    rules: {
      "no-console": [0],
    },
  },
]

module.exports = config

with eslint.config.ts file:

import eslint from "@eslint/js"
import type { Linter } from "eslint"

const config: Linter.FlatConfig[] = [
  eslint.configs.recommended,
  {
    rules: {
      "no-console": [0],
    },
  },
]

export default config

Documentation

The documentation for this feature will be added to the ESLint User Guide page. The documentation will explain how to use TypeScript configuration files and the differences between JavaScript and TypeScript configuration files.

Drawbacks

This change will most likely require at least one external tool as either a dependency or a peer dependency.

Backwards Compatibility Analysis

This goal is to minimize the disruption to existing users. The primary focus is to ensure that the existing JavaScript configuration files continue to work as expected. The changes will only affect TypeScript users who are using TypeScript configuration files. The changes will not affect the existing JavaScript configuration files.

Alternatives

While developing this feature, we considered the following alternatives:

  1. Using ts-node to parse TypeScript configuration files. This approach proved to be problematic because ts-node hooks into Node.js's native module resolution system, which could potentially cause side effects.

  2. Using tsx to parse TypeScript configuration files. This approach also proved to be problematic because tsx hooks into Node.js's native module resolution system, which could potentially cause side effects.

  3. Using TypeScript's transpileModule() to parse TypeScript configuration files. This approach proved to be problematic because it requires a significant amount of overhead and is not suitable for this purpose.

Open Questions

  1. How is caching going to work with TypeScript config files?
  2. Should we look at the nearest tsconfig.json file to determine the module resolution for eslint.config.ts files? Most likely not, but it's worth considering.
  3. Should we allow some sort of interoperability between JavaScript and TypeScript configuration files? For example, should we allow a TypeScript configuration file to extend a JavaScript configuration file and vice versa?
  4. Should we allow eslint.config.ts to be able to use export default as well as module.exports (might be related to TypeScript's automatic Module Detection)?

Help Needed

I will be implementing this feature. I will need help from the team to review the code and provide feedback.

Frequently Asked Questions

Related Discussions

This PR is related to this RFC. Prior Discussion related to supporting .eslintrc.ts files. Prior Issue related to supporting .eslintrc.ts files.

External References