# ESLint Presets

The module `eslint` provides a `defineConfig` function to create a project-wide ESLint configuration (e.g. TypeScript files, JSON files, license headers, etc.), and a set of environment presets that apply more ESLint plugins and rules to a specific subset of the project (e.g. browser code, unit test code, etc.).

## Functions

### Function `defineConfig`

Generates standard configuration targeting the source files in the entire project, and allows to add more custom configuration entries. Internally, various ESLint plugins will be included and configured to use their recommended rule sets.

| Target | ESLint Plugin |
| - | - |
| JavaScript and TypeScript files (including `.jsx` and `.tsx`) | ESLint core rules |
| JavaScript files only (including `.jsx`) | ESLint core rules |
| TypeScript files with type-aware rules (including `.tsx`) | [typescript-eslint](https://typescript-eslint.io/) |
| [Vue.js](https://vuejs.org) files (`.vue`) | [eslint-plugin-vue](https://eslint.vuejs.org) |
| JSON files (`.json`) | [eslint-plugin-jsonc](https://ota-meshi.github.io/eslint-plugin-jsonc/) |
| YAML files (`.yaml`, `.yml`) | [eslint-plugin-yml](https://ota-meshi.github.io/eslint-plugin-yml/) |
| Markdown files (`.md`) | [@eslint/markdown](https://github.com/eslint/markdown) |
| License headers | [eslint-plugin-license-header](https://github.com/nikku/eslint-plugin-license-header) |
| ESLint inline directives | [@eslint-community/eslint-plugin-eslint-comments](https://github.com/eslint-community/eslint-plugin-eslint-comments) |
| Outdated dependencies | [eslint-plugin-depend](https://github.com/es-tooling/eslint-plugin-depend) |
| Regular expressions | [eslint-plugin-regexp](https://ota-meshi.github.io/eslint-plugin-regexp/) |
| Native ES6 promises | [eslint-plugin-promise](https://github.com/eslint-community/eslint-plugin-promise) |
| JSDoc source documentation | [eslint-plugin-jsdoc](https://github.com/gajus/eslint-plugin-jsdoc) |
| Source code formatting | [@stylistic/eslint-plugin](https://eslint.style/packages/default) |

#### `defineConfig` Signature

```ts
function defineConfig(options: ProjectOptions, ...configs: ConfigArg[]): Config[]
```

After the mandatory `options` parameters, the function can take multiple custom configuration objects or arrays, for example environment configuration presets (see below).

#### `defineConfig` Options

| Name | Type | Default | Description |
| - | - | - | - |
| `ignores` | `string[]` | `[]` | Glob patterns with all files and folders to be ignored by ESLint. This package already defines a few standard ignore globs (see below). |
| `license` | `string` | `''` | Full path to the template file containing the license header to be used in all source files. |
| `language` | `LanguageOptions` | | Configuration options for language and project setup. |
| `language.ecmaVersion` | `number\|'latest'` | `'latest'` | The ECMAScript version to be used in the project (version or year). |
| `language.sourceType` | `'module'\|'commonjs'` | `'module'` | Specifies how to treat `.js`, `.jsx`, `.ts`, and `.tsx` files. |
| `packages` | `PackagesOptions` | | Configuration options for external package dependencies. |
| `packages.allowed` | `string[]` | `[]` | Banned packages to be allowed in the project. |
| `packages.banned` | `string[]` | `[]` | Additional packages to be banned in the project. |
| `stylistic` | `StylisticOptions` | | Configuration options for code style. |
| `stylistic.indent` | `number` | `2` | Default indentation size (number of space characters) for all file types. |
| `stylistic.indentOverrides` | `IndentOverridesOptions` | `{}` | Custom indentation overrides per file type. |
| `stylistic.indentOverrides.js` | `number` | | JavaScript and TypeScript files (including `.jsx`, `.tsx`). |
| `stylistic.indentOverrides.json` | `number` | | JSON files (`.json`). |
| `stylistic.indentOverrides.yaml` | `number` | | YAML files (`.yaml`, `.yml`). |
| `stylistic.indentOverrides.vue` | `number` | | Vue.js files (`.vue`). |
| `stylistic.semi` | `'always'\|'never'\|'off'` | `'never'` | Specifies whether to require semicolons following all statements (`'always'`), or to force to omit semicolons if possible according to ASI rules (`'never'`). |
| `stylistic.quotes` | `'single'\|'double'\|'off'` | `'single'` | The type of the string delimiter character. |
| `stylistic.dangle` | `'always'\|'never'\|'off'` | `'always'` | Specifies how to treat dangling commas in multiline lists. |
| `vue` | `VueOptions` | `{}` | Additional options for Vue specific rules. |
| `vue.globalDirectives` | `string[]` | `[]` | Names of all globally registered directives to be ignored by the rule [`vue/no-undef-directives`](https://eslint.vuejs.org/rules/no-undef-directives.html) (without 'v-' prefix). |
| `rules` | `RulesConfig` | `{}` | Additional linter rules to be added to the global configuration. |

#### Built-in Ignore Globs

This package defines ignore globs for the following files and directories:

- `*/.yarn` (internal setup files of Yarn v2+)
- `dist` (standard build output directory)
- `output` (output directory for tests etc.)
- `vite.config.ts.*.mjs` (intermediate files of Vite dev server)
- `gitlab-ci` and `.gitlab-ci.yml` (GitLab CI configuration files)
- `coverage` (Vitest coverage results)
- `.nuxt` and `.output` (NuxtJS output directories)

Custom ignore globs passed in the options will be added to the built-in ignore list.

#### `defineConfig` Example

```ts
// eslint.config.ts
import { defineConfig } from '@open-xchange/linter-presets/eslint'

export default defineConfig({
  ignores: ['external/**/*.yaml'],
  language: { ecmaVersion: 2024, sourceType: 'commonjs' },
  license: './license.txt',
  stylistic: { quotes: 'single', semi: 'never' },
})
```

## Environment Presets

Environment presets will be applied to specific subsets of the project. Usually, they import one or more external ESLint plugins, apply their recommended rule set, and add or modify a few of their rules to establish the default setup for the project. All environment presets allow to pass rule records to override the recommended rules.

All environment presets are available in the `env` dictionary exported from the `eslint` module.

### Overview

The names of the environment presets are linked to detailed descriptions.

| Name | Description |
| - | - |
| [`env.node`](./env/node.md) | Modules running in NodeJS. |
| [`env.browser`](./env/browser.md) | Modules running in browsers. |
| [`env.react`](./env/react.md) | Modules using [React](https://react.dev/). |
| [`env.jest`](./env/jest.md) | Unit tests with [Jest](https://jestjs.io/). |
| [`env.vitest`](./env/vitest.md) | Unit tests with [Vitest](https://vitest.dev/). |
| [`env.codecept`](./env/codecept.md) | E2E tests with [CodeceptJS](https://codecept.io/). |
| [`env.eslint`](./env/eslint.md) | Implementation of custom ESLint rules. |
| [`env.project`](./env/project.md) | Project setup and module imports. |
| [`env.tsconfig`](./env/tsconfig.md) | TypeScript project setup (per `tsconfig.json` file). Provided in case VSCode fails to use the new project service correctly. |
| [`env.decorators`](./env/decorators.md) | Support for native decorators in JavaScript source files. |

## Example

```ts
// eslint.config.ts
import { defineConfig, env } from '@open-xchange/linter-presets/eslint'

export default defineConfig(

  // project configuration options
  { /* ... */ },

  // NodeJS environment
  env.node({
    files: ['src/server/**'],
  }),

  // Browser environment
  env.browser({
    files: ['src/client/**'],
  }),

  // custom configuration
  {
    files: ['src/**'],
    rules: {
      // ...
    },
  },
)
```
