# Advanced Configuration

## Configuration Examples

### Vue 3, Nuxt and Laravel Inertia

Use the purpose-built entrypoints rather than composing this by hand: `/vue3` for plain Vue 3 (Vite, Laravel
Inertia, or any non-Nuxt setup) and `/nuxt` for Nuxt. Each entrypoint owns every file type it lints, so
neither needs pairing. Order matters in one case: nothing carrying the house rule set may follow `/nuxt`. See [Vue 3 and Nuxt Guide](05-vue-and-nuxt.md).

`/vue3` includes the base config and lints `.vue` and the TypeScript extensions itself:

```js
import bitfactoryVue3 from '@bitfactory/eslint-config/vue3';
import gitignore from 'eslint-config-flat-gitignore';

export default [
    gitignore(),
    ...bitfactoryVue3,
];
```

`/nuxt` is `/vue3` plus the Nuxt layer, so it needs nothing else either:

```js
import bitfactoryNuxt from '@bitfactory/eslint-config/nuxt';
import gitignore from 'eslint-config-flat-gitignore';

export default [
    gitignore(),
    ...bitfactoryNuxt,
];
```

Adding `/typescript` alongside `/vue3` still works and changes nothing, so an existing configuration that
writes it does not need editing.

### Which entrypoint owns which file type

| entrypoint | lints |
| --- | --- |
| `.` (base) | `.js`, `.mjs`, `.cjs` |
| `/typescript` | the base extensions plus `.ts`, `.tsx`, `.mts`, `.cts` |
| `/vue` | the base extensions plus `.vue` (Vue 2, deprecated) |
| `/vue3` | the base extensions plus `.ts`, `.tsx`, `.mts`, `.cts` and `.vue` |
| `/nuxt` | everything `/vue3` lints, plus `.jsx` |

Each of them applies the same house rule set to every file type in its row, so the same construct is judged
the same way whichever entrypoint you compose. A file type absent from your chosen row is skipped rather
than linted.

`/json`, `/package-json`, `/tailwind` and `/tailwind-vue` are add-ons in the sense that they apply no house
rule set: each carries its own plugins' rules for the files it names, and parses those files, so each also
works on its own.

### TypeScript only

```js
import bitfactoryBase from '@bitfactory/eslint-config';
import bitfactoryTypeScript from '@bitfactory/eslint-config/typescript';
import gitignore from 'eslint-config-flat-gitignore';

export default [
    gitignore(),
    ...bitfactoryBase,
    ...bitfactoryTypeScript,
];
```

### Vue 2 (support deprecated)

```js
import bitfactoryBase from '@bitfactory/eslint-config';
import bitfactoryVue from '@bitfactory/eslint-config/vue';
import gitignore from 'eslint-config-flat-gitignore';

export default [
    gitignore(),
    ...bitfactoryBase,
    ...bitfactoryVue,
];
```

**With TypeScript**, `/vue` needs nothing extra. It supplies `@typescript-eslint/parser` as the script
sub-parser itself, so a `<script lang="ts">` block in a Vue 2 SFC is parsed rather than reported as a syntax
error (ADR-0026). Compose `/typescript` beside it only for standalone `.ts` files, which `/vue` does not claim:

```js
import bitfactoryTypeScript from '@bitfactory/eslint-config/typescript';
import bitfactoryVue from '@bitfactory/eslint-config/vue';
import gitignore from 'eslint-config-flat-gitignore';

export default [
    gitignore(),
    ...bitfactoryVue,
    ...bitfactoryTypeScript,
];
```

Vue 2 support is deprecated rather than removed. On Vue 3 use `/vue3`, which claims `.ts` as well and needs no
second entrypoint.

## Custom Configuration

### Adding Custom Plugins

```js
import bitfactoryBase from '@bitfactory/eslint-config';
import gitignore from 'eslint-config-flat-gitignore';
import yourPlugin from 'eslint-plugin-your-plugin';

export default [
    gitignore(),
    ...bitfactoryBase,
    {
        plugins: {
            'your-plugin': yourPlugin,
        },
        rules: {
            'your-plugin/rule-name': 'error',
        },
    },
];
```

### Override ECMAScript Version

From `12.0.2` the base config parses `**/*.{js,mjs}` at `ecmaVersion: 'latest'` so modern syntax such as
top-level `await` is accepted. `**/*.cjs` stays at `2021`, because those files are parsed as scripts and a
newer `ecmaVersion` would add globals to the script scope that `no-redeclare` then reports.

One upgrade note: newer `ecmaVersion` values define more globals, so an `eslint-disable no-undef` you kept
only to silence a global such as `Iterator` or `Float16Array` is now unnecessary and reports as an unused
directive. Deleting the comment is the fix.

```js
{
    files: ['**/*.cjs'],
    languageOptions: {
        ecmaVersion: 'latest', // .cjs defaults to 2021; .js and .mjs are already 'latest'
    },
}
```

### Enable Type-Aware Linting (TypeScript)

> [!WARNING]
> Type-aware linting is significantly slower than regular linting but provides much more thorough error detection. Only enable it if you need the extra type safety and can afford the performance cost.
>
> `13.0.0` also stopped setting `@typescript-eslint/only-throw-error`. Being type-aware, it could not load
> until type information was enabled, which aborted the run on every `.ts` file. `.ts` files use the base
> `no-throw-literal` rule instead; once type-aware linting is on, set `only-throw-error` yourself to get the
> stronger check back.

TypeScript-ESLint v8 introduced a stable **Project Service** feature that makes type-aware linting easier to configure:

```js
import bitfactoryBase from '@bitfactory/eslint-config';
import bitfactoryTypeScript from '@bitfactory/eslint-config/typescript';
import gitignore from 'eslint-config-flat-gitignore';
import tsParser from '@typescript-eslint/parser';

export default [
    gitignore(),
    ...bitfactoryBase,
    ...bitfactoryTypeScript,
    {
        files: ['**/*.ts', '**/*.tsx'],
        languageOptions: {
            parser: tsParser,
            parserOptions: {
                projectService: true, // Enable Project Service
            },
        },
    },
];
```

**Benefits of type-aware linting:**

- Catches type-related errors that basic linting misses
- Enables advanced rules like `no-floating-promises`, `no-misused-promises`, etc.
- Automatically locates the nearest `tsconfig.json`

**Alternative: Specify tsconfig explicitly:**

```js
{
    languageOptions: {
        parser: tsParser,
        parserOptions: {
            project: './tsconfig.json', // Explicit path to tsconfig
        },
    },
}
```

See the [typescript-eslint typed linting docs](https://typescript-eslint.io/getting-started/typed-linting/) for more details.
