@enke.dev/lint 0.12.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -15
- package/configs/eslint/bun.config.d.ts +3 -0
- package/configs/eslint/bun.config.js +11 -0
- package/configs/eslint/html.config.d.ts +2 -0
- package/configs/eslint/html.config.js +43 -0
- package/configs/eslint/json.config.d.ts +2 -0
- package/configs/eslint/json.config.js +14 -0
- package/configs/eslint/lit.config.d.ts +2 -0
- package/configs/eslint/lit.config.js +38 -0
- package/configs/eslint/node.config.d.ts +3 -0
- package/configs/eslint/node.config.js +10 -0
- package/configs/eslint/typescript.config.d.ts +12 -0
- package/configs/eslint/typescript.config.js +100 -0
- package/eslint.config.d.ts +22 -4
- package/eslint.config.js +25 -169
- package/package.json +59 -18
- package/presets/eslint/bun-library.preset.d.ts +3 -0
- package/presets/eslint/bun-library.preset.js +8 -0
- package/presets/eslint/frontend.preset.d.ts +3 -0
- package/presets/eslint/frontend.preset.js +16 -0
- package/presets/eslint/node-library.preset.d.ts +3 -0
- package/presets/eslint/node-library.preset.js +8 -0
package/README.md
CHANGED
|
@@ -21,7 +21,16 @@ npm i -D jiti typescript typescript-eslint
|
|
|
21
21
|
|
|
22
22
|
## Prepare Eslint config
|
|
23
23
|
|
|
24
|
-
Create a `eslint.config.js` (or `eslint.config.ts`) file in the root of your project
|
|
24
|
+
Create a `eslint.config.js` (or `eslint.config.ts`) file in the root of your project. There are three ways to consume the configuration, from least to most control: the legacy all-in-one config, a ready-made preset, or the individual single configs.
|
|
25
|
+
|
|
26
|
+
> [!NOTE]
|
|
27
|
+
> Using Typescript may require the root directory where to find the `tsconfig.json` to be specified.\
|
|
28
|
+
> Therefore, a convenience function `setTsConfigRootDir` is provided to configure this option globally.
|
|
29
|
+
|
|
30
|
+
### 1. Legacy config
|
|
31
|
+
|
|
32
|
+
> [!WARNING]
|
|
33
|
+
> The default export is **deprecated**. It bundles `node` + `lit` + `html` + `json` and additionally assumes gitignore-based ignores and this package's own tsconfig root — assumptions that do not hold for every project. Prefer a [preset](#2-presets) or [single configs](#3-single-configs).
|
|
25
34
|
|
|
26
35
|
```js
|
|
27
36
|
import config from '@enke.dev/lint';
|
|
@@ -29,27 +38,90 @@ import config from '@enke.dev/lint';
|
|
|
29
38
|
export default config;
|
|
30
39
|
```
|
|
31
40
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
41
|
+
### 2. Presets
|
|
42
|
+
|
|
43
|
+
Ready-made combinations for common project types. Import the one that matches your project and export it directly:
|
|
44
|
+
|
|
45
|
+
```ts
|
|
46
|
+
import { frontend } from '@enke.dev/lint/eslint/presets/frontend';
|
|
47
|
+
|
|
48
|
+
export default frontend;
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Available presets:
|
|
52
|
+
|
|
53
|
+
| Preset | Import name | Bundles |
|
|
54
|
+
| -------------------------------------------- | ------------- | -------------------------------- |
|
|
55
|
+
| `@enke.dev/lint/eslint/presets/frontend` | `frontend` | `node` + `lit` + `html` + `json` |
|
|
56
|
+
| `@enke.dev/lint/eslint/presets/node-library` | `nodeLibrary` | `node` + `json` |
|
|
57
|
+
| `@enke.dev/lint/eslint/presets/bun-library` | `bunLibrary` | `bun` + `json` |
|
|
58
|
+
|
|
59
|
+
Presets are flat config arrays, so they can be extended — e.g. to point the TypeScript parser at your `tsconfig.json`:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { defineConfig } from 'eslint/config';
|
|
63
|
+
|
|
64
|
+
import { setTsConfigRootDir } from '@enke.dev/lint';
|
|
65
|
+
import { frontend } from '@enke.dev/lint/eslint/presets/frontend';
|
|
35
66
|
|
|
36
|
-
|
|
67
|
+
export default defineConfig([...frontend, setTsConfigRootDir(import.meta.dirname)]);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 3. Single configs
|
|
37
71
|
|
|
38
|
-
For
|
|
72
|
+
For full control, compose the individual chunks yourself. Each is a flat config array; spread the ones you need:
|
|
39
73
|
|
|
40
74
|
```ts
|
|
41
|
-
import
|
|
75
|
+
import { defineConfig } from 'eslint/config';
|
|
76
|
+
|
|
77
|
+
import { bun } from '@enke.dev/lint/eslint/bun';
|
|
78
|
+
import { html } from '@enke.dev/lint/eslint/html';
|
|
79
|
+
import { json } from '@enke.dev/lint/eslint/json';
|
|
80
|
+
import { lit } from '@enke.dev/lint/eslint/lit';
|
|
42
81
|
|
|
43
82
|
export default defineConfig([
|
|
44
|
-
//
|
|
45
|
-
...
|
|
46
|
-
//
|
|
47
|
-
|
|
83
|
+
...bun, // TypeScript + import rules, bun module resolver
|
|
84
|
+
...lit, // web components, lit and inline-html linting
|
|
85
|
+
...html, // standalone .html files
|
|
86
|
+
...json, // .json files
|
|
48
87
|
]);
|
|
49
88
|
```
|
|
50
89
|
|
|
51
|
-
|
|
52
|
-
|
|
90
|
+
Available configs:
|
|
91
|
+
|
|
92
|
+
| Import | Name | Applies to | Notes |
|
|
93
|
+
| ---------------------------- | ------ | ----------------- | --------------------------------------------------------------- |
|
|
94
|
+
| `@enke.dev/lint/eslint/node` | `node` | `**/*.js`, `*.ts` | Base TS/import rules, node resolver. |
|
|
95
|
+
| `@enke.dev/lint/eslint/bun` | `bun` | `**/*.js`, `*.ts` | Same base, bun resolver (resolves `bun:test`, `bun:sqlite`, …). |
|
|
96
|
+
| `@enke.dev/lint/eslint/lit` | `lit` | `**/*.js`, `*.ts` | Web components, lit, a11y and inline-html rules. |
|
|
97
|
+
| `@enke.dev/lint/eslint/html` | `html` | `**/*.html` | Standalone HTML files. |
|
|
98
|
+
| `@enke.dev/lint/eslint/json` | `json` | `**/*.json` | JSON files. |
|
|
99
|
+
|
|
100
|
+
> [!NOTE]
|
|
101
|
+
> `node` and `bun` differ only by the import resolver — pick one.
|
|
102
|
+
|
|
103
|
+
### Type-aware linting
|
|
104
|
+
|
|
105
|
+
By default the rules are syntactic only (typescript-eslint `strict` + `stylistic`), so no `tsconfig` is required. Every TypeScript base — the `node` / `bun` single configs and all three presets — additionally ships a **type-checked** variant that enables the type-aware rule sets (`strictTypeChecked` + `stylisticTypeChecked`, e.g. `no-floating-promises`, `no-misused-promises`, `await-thenable`).
|
|
106
|
+
|
|
107
|
+
Each variant is an extra export from the same module — just add the `TypeChecked` suffix:
|
|
108
|
+
|
|
109
|
+
| Base | Type-checked variant | Import from |
|
|
110
|
+
| ------------- | ------------------------ | -------------------------------------------- |
|
|
111
|
+
| `node` | `nodeTypeChecked` | `@enke.dev/lint/eslint/node` |
|
|
112
|
+
| `bun` | `bunTypeChecked` | `@enke.dev/lint/eslint/bun` |
|
|
113
|
+
| `frontend` | `frontendTypeChecked` | `@enke.dev/lint/eslint/presets/frontend` |
|
|
114
|
+
| `nodeLibrary` | `nodeLibraryTypeChecked` | `@enke.dev/lint/eslint/presets/node-library` |
|
|
115
|
+
| `bunLibrary` | `bunLibraryTypeChecked` | `@enke.dev/lint/eslint/presets/bun-library` |
|
|
116
|
+
|
|
117
|
+
```ts
|
|
118
|
+
import { frontendTypeChecked } from '@enke.dev/lint/eslint/presets/frontend';
|
|
119
|
+
|
|
120
|
+
export default frontendTypeChecked;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
> [!WARNING]
|
|
124
|
+
> Type-aware rules require a TypeScript program. The variants enable `projectService`, which auto-discovers the nearest `tsconfig.json` — but any file **not** covered by one (stray configs, generated JS) will error unless you configure [`parserOptions.projectService.allowDefaultProject`](https://typescript-eslint.io/packages/parser/#projectservice). Type-aware linting is also noticeably slower.
|
|
53
125
|
|
|
54
126
|
### Using Monorepos
|
|
55
127
|
|
|
@@ -96,11 +168,19 @@ For now, [no TypeScript support](https://github.com/stylelint/stylelint/issues/4
|
|
|
96
168
|
|
|
97
169
|
## Development
|
|
98
170
|
|
|
171
|
+
Prerequisites:
|
|
172
|
+
|
|
173
|
+
- **Node** — version pinned in [`.node-version`](.node-version) (use `nvm`/`fnm` to match it).
|
|
174
|
+
- **[bun](https://bun.sh/)** — required for the `test:bun` suite; install it globally (`curl -fsSL https://bun.sh/install | bash`).
|
|
175
|
+
|
|
99
176
|
This repo self-tests the configuration by linting itself: `npm run lint`.\
|
|
100
177
|
Therefore, a `test.eslint.config.ts` is used.
|
|
101
178
|
|
|
102
|
-
And additionally,
|
|
103
|
-
|
|
179
|
+
And additionally, naive tests are in place to check that the linter actually finds issues: `npm run test`.\
|
|
180
|
+
This runs two suites:
|
|
181
|
+
|
|
182
|
+
- `npm run test:node` — the native Node test runner against obviously faulty code in the `test` directory (default/legacy config, prettier, stylelint).
|
|
183
|
+
- `npm run test:bun` — the bun test runner (`test.run.bun.ts`), which exercises the `bun` and type-checked configs against the source directly (bun resolves `.js`→`.ts`, so no build is needed). Requires [bun](https://bun.sh/).
|
|
104
184
|
|
|
105
185
|
### Updating dependencies
|
|
106
186
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
|
|
3
|
+
import { typescript } from './typescript.config.js';
|
|
4
|
+
// Same base as `node`, but with the bun module resolver so builtins such as
|
|
5
|
+
// `bun:test` and `bun:sqlite` resolve instead of being flagged as unresolved.
|
|
6
|
+
export const bun = defineConfig([eslintPluginPrettierRecommended, typescript('bun')]);
|
|
7
|
+
// Same as `bun`, plus type-aware rules (needs a tsconfig; see `TypescriptOptions`).
|
|
8
|
+
export const bunTypeChecked = defineConfig([
|
|
9
|
+
eslintPluginPrettierRecommended,
|
|
10
|
+
typescript('bun', { typeChecked: true }),
|
|
11
|
+
]);
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import eslintPluginHtml from '@html-eslint/eslint-plugin';
|
|
2
|
+
import eslintParserHtml from '@html-eslint/parser';
|
|
3
|
+
import { defineConfig } from 'eslint/config';
|
|
4
|
+
import eslintPluginHtmlScripts from 'eslint-plugin-html';
|
|
5
|
+
import { parserOptions } from './typescript.config.js';
|
|
6
|
+
// Standalone HTML files.
|
|
7
|
+
const htmlConfig = {
|
|
8
|
+
files: ['**/*.html'],
|
|
9
|
+
plugins: {
|
|
10
|
+
html: eslintPluginHtml,
|
|
11
|
+
htmlScripts: eslintPluginHtmlScripts,
|
|
12
|
+
},
|
|
13
|
+
extends: ['html/recommended'],
|
|
14
|
+
language: 'html/html',
|
|
15
|
+
languageOptions: {
|
|
16
|
+
parser: eslintParserHtml,
|
|
17
|
+
parserOptions,
|
|
18
|
+
},
|
|
19
|
+
settings: {
|
|
20
|
+
'html/indent': '+2',
|
|
21
|
+
'html/lowercase': 'error',
|
|
22
|
+
'html/no-accesskey-attrs': 'error',
|
|
23
|
+
'html/no-aria-hidden-body': 'error',
|
|
24
|
+
'html/no-aria-hidden-on-focusable': 'error',
|
|
25
|
+
'html/no-duplicate-class': 'error',
|
|
26
|
+
'html/no-duplicate-in-head': 'error',
|
|
27
|
+
'html/no-empty-headings': 'error',
|
|
28
|
+
'html/no-invalid-entities': 'error',
|
|
29
|
+
'html/no-heading-inside-button': 'error',
|
|
30
|
+
'html/no-invalid-entity': 'error',
|
|
31
|
+
'html/no-invalid-role': 'error',
|
|
32
|
+
'html/no-nested-interactive': 'error',
|
|
33
|
+
'html/no-multiple-empty-lines': 'error',
|
|
34
|
+
'html/no-target-blank': 'error',
|
|
35
|
+
'html/no-trailing-spaces': 'error',
|
|
36
|
+
'html/report-bad-indent': 'error',
|
|
37
|
+
'html/require-input-label': 'error',
|
|
38
|
+
},
|
|
39
|
+
rules: {
|
|
40
|
+
'html/indent': ['error', 2],
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
export const html = defineConfig([htmlConfig]);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import eslintPluginJson from '@eslint/json';
|
|
2
|
+
import { defineConfig } from 'eslint/config';
|
|
3
|
+
// JSON files.
|
|
4
|
+
const jsonConfig = {
|
|
5
|
+
files: ['**/*.json'],
|
|
6
|
+
language: 'json/json',
|
|
7
|
+
ignores: ['package-lock.json'],
|
|
8
|
+
plugins: { json: eslintPluginJson },
|
|
9
|
+
extends: [eslintPluginJson.configs.recommended],
|
|
10
|
+
rules: {
|
|
11
|
+
'json/top-level-interop': 'error',
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export const json = defineConfig([jsonConfig]);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import eslintPluginHtml from '@html-eslint/eslint-plugin';
|
|
2
|
+
import { defineConfig } from 'eslint/config';
|
|
3
|
+
import eslintPluginHtmlScripts from 'eslint-plugin-html';
|
|
4
|
+
import { configs as eslintPluginLitConfigs } from 'eslint-plugin-lit';
|
|
5
|
+
import { configs as eslintPluginLitA11yConfigs } from 'eslint-plugin-lit-a11y';
|
|
6
|
+
import { configs as eslintPluginWebComponentsConfigs } from 'eslint-plugin-wc';
|
|
7
|
+
import { parserOptions } from './typescript.config.js';
|
|
8
|
+
// Lit / web-components support: element rules, a11y, and inline html-in-tagged-template linting.
|
|
9
|
+
const litConfig = {
|
|
10
|
+
files: ['**/*.js', '**/*.ts'],
|
|
11
|
+
extends: [
|
|
12
|
+
eslintPluginWebComponentsConfigs['flat/recommended'],
|
|
13
|
+
eslintPluginLitConfigs['flat/recommended'],
|
|
14
|
+
eslintPluginLitA11yConfigs.recommended,
|
|
15
|
+
],
|
|
16
|
+
plugins: {
|
|
17
|
+
html: eslintPluginHtml,
|
|
18
|
+
htmlScripts: eslintPluginHtmlScripts,
|
|
19
|
+
},
|
|
20
|
+
languageOptions: { parserOptions },
|
|
21
|
+
settings: {
|
|
22
|
+
litHtmlSources: true,
|
|
23
|
+
},
|
|
24
|
+
rules: {
|
|
25
|
+
// inline html
|
|
26
|
+
'html/require-img-alt': 'error',
|
|
27
|
+
'html/no-multiple-h1': 'error',
|
|
28
|
+
'html/no-extra-spacing-attrs': 'error',
|
|
29
|
+
'html/no-duplicate-id': 'error',
|
|
30
|
+
'html/require-li-container': 'error',
|
|
31
|
+
'html/no-obsolete-tags': 'error',
|
|
32
|
+
'html/require-closing-tags': 'error',
|
|
33
|
+
'html/no-duplicate-attrs': 'error',
|
|
34
|
+
// web components / a11y
|
|
35
|
+
'wc/guard-super-call': 'off',
|
|
36
|
+
},
|
|
37
|
+
};
|
|
38
|
+
export const lit = defineConfig([litConfig]);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
|
|
3
|
+
import { typescript } from './typescript.config.js';
|
|
4
|
+
// TypeScript / JavaScript for projects that emit via tsc and run on node.
|
|
5
|
+
export const node = defineConfig([eslintPluginPrettierRecommended, typescript('node')]);
|
|
6
|
+
// Same as `node`, plus type-aware rules (needs a tsconfig; see `TypescriptOptions`).
|
|
7
|
+
export const nodeTypeChecked = defineConfig([
|
|
8
|
+
eslintPluginPrettierRecommended,
|
|
9
|
+
typescript('node', { typeChecked: true }),
|
|
10
|
+
]);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Linter } from 'eslint';
|
|
2
|
+
import type { Config } from 'eslint/config';
|
|
3
|
+
import { defineConfig } from 'eslint/config';
|
|
4
|
+
export type FlatConfig = ReturnType<typeof defineConfig>;
|
|
5
|
+
export type ConfigWithExtends = Exclude<Parameters<typeof defineConfig>[number], readonly unknown[]>;
|
|
6
|
+
export declare const parserOptions: Linter.ParserOptions;
|
|
7
|
+
export declare function setTsConfigRootDir(dir: string): Config;
|
|
8
|
+
export declare const importSortGroups: string[][];
|
|
9
|
+
export interface TypescriptOptions {
|
|
10
|
+
typeChecked?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare function typescript(runtime: 'node' | 'bun', { typeChecked }?: TypescriptOptions): ConfigWithExtends;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { fixupPluginRules } from '@eslint/compat';
|
|
2
|
+
import eslintPluginJs from '@eslint/js';
|
|
3
|
+
import eslintPluginImport from 'eslint-plugin-import';
|
|
4
|
+
import eslintPluginImportExtension from 'eslint-plugin-import-extensions';
|
|
5
|
+
import eslintPluginSimpleImportSort from 'eslint-plugin-simple-import-sort';
|
|
6
|
+
import eslintPluginUnusedImports from 'eslint-plugin-unused-imports';
|
|
7
|
+
import eslintTs from 'typescript-eslint';
|
|
8
|
+
// shared parser options
|
|
9
|
+
export const parserOptions = {
|
|
10
|
+
ecmaVersion: 'latest',
|
|
11
|
+
sourceType: 'module',
|
|
12
|
+
};
|
|
13
|
+
export function setTsConfigRootDir(dir) {
|
|
14
|
+
return { languageOptions: { parserOptions: { project: true, tsconfigRootDir: dir } } };
|
|
15
|
+
}
|
|
16
|
+
// shared import-sort groups
|
|
17
|
+
export const importSortGroups = [
|
|
18
|
+
// Side effect imports.
|
|
19
|
+
['^\\u0000'],
|
|
20
|
+
// Node.js builtins prefixed with `node:`.
|
|
21
|
+
['^node:'],
|
|
22
|
+
// Packages.
|
|
23
|
+
// Things that start with a letter (or digit or underscore), or `@` followed by a letter.
|
|
24
|
+
['^@?\\w'],
|
|
25
|
+
// Absolute imports and other imports such as Vue-style `@/foo`.
|
|
26
|
+
// Anything not matched in another group.
|
|
27
|
+
['^'],
|
|
28
|
+
// Relative imports.
|
|
29
|
+
// Anything that starts with a dot.
|
|
30
|
+
['^\\.'],
|
|
31
|
+
// Assetic imports, most likely inline loaded style files for lit components
|
|
32
|
+
// or raw loaded files like images, meta data or fonts.
|
|
33
|
+
['\\?(inline|raw)$'],
|
|
34
|
+
];
|
|
35
|
+
// JavaScript / TypeScript base config, parametrised by runtime target.
|
|
36
|
+
//
|
|
37
|
+
// Relative imports always carry the emitted `.js` extension: tsc emits `.js`, and
|
|
38
|
+
// runtimes that execute TypeScript directly (bun, ts-node, --experimental-strip-types)
|
|
39
|
+
// resolve a `.js` specifier back to the neighbouring `.ts` source anyway. `runtime`
|
|
40
|
+
// therefore only switches the resolver, so bun builtins (`bun:test`, `bun:sqlite`) are
|
|
41
|
+
// recognised rather than flagged as unresolved.
|
|
42
|
+
export function typescript(runtime, { typeChecked = false } = {}) {
|
|
43
|
+
return {
|
|
44
|
+
files: ['**/*.js', '**/*.ts'],
|
|
45
|
+
extends: [
|
|
46
|
+
eslintPluginJs.configs.recommended,
|
|
47
|
+
...(typeChecked ? eslintTs.configs.strictTypeChecked : eslintTs.configs.strict),
|
|
48
|
+
...(typeChecked ? eslintTs.configs.stylisticTypeChecked : eslintTs.configs.stylistic),
|
|
49
|
+
eslintPluginImport.flatConfigs.recommended,
|
|
50
|
+
],
|
|
51
|
+
plugins: {
|
|
52
|
+
'simple-import-sort': eslintPluginSimpleImportSort,
|
|
53
|
+
'unused-imports': eslintPluginUnusedImports,
|
|
54
|
+
'import-extensions': fixupPluginRules(eslintPluginImportExtension),
|
|
55
|
+
},
|
|
56
|
+
// type-aware rules need a program; projectService (tseslint v8) auto-discovers tsconfig
|
|
57
|
+
languageOptions: {
|
|
58
|
+
parserOptions: typeChecked ? { ...parserOptions, projectService: true } : parserOptions,
|
|
59
|
+
},
|
|
60
|
+
settings: {
|
|
61
|
+
'import/resolver': {
|
|
62
|
+
typescript: runtime === 'bun' ? { bun: true, node: true } : { node: true },
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
rules: {
|
|
66
|
+
// formatting
|
|
67
|
+
'@typescript-eslint/no-unused-expressions': [
|
|
68
|
+
'error',
|
|
69
|
+
{ allowShortCircuit: true, allowTernary: true },
|
|
70
|
+
],
|
|
71
|
+
curly: 'error',
|
|
72
|
+
'linebreak-style': ['error', 'unix'],
|
|
73
|
+
quotes: ['error', 'single', { avoidEscape: true }],
|
|
74
|
+
semi: ['error', 'always'],
|
|
75
|
+
'no-console': 'error',
|
|
76
|
+
// import sorting
|
|
77
|
+
'simple-import-sort/imports': ['error', { groups: importSortGroups }],
|
|
78
|
+
'simple-import-sort/exports': 'error',
|
|
79
|
+
// import extensions
|
|
80
|
+
'import-extensions/require-extensions': ['error', { expectedExtensions: ['js'] }],
|
|
81
|
+
'import-extensions/require-index': ['error', { expectedExtensions: ['js'] }],
|
|
82
|
+
// import rules
|
|
83
|
+
'import/enforce-node-protocol-usage': ['error', 'always'], // enforce node: import prefix
|
|
84
|
+
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'], // type imports
|
|
85
|
+
'import/first': 'error',
|
|
86
|
+
'import/newline-after-import': 'error',
|
|
87
|
+
'import/no-duplicates': 'error',
|
|
88
|
+
'import/no-unresolved': 'error',
|
|
89
|
+
'import/extensions': ['error', 'ignorePackages', { ts: 'never', js: 'always' }],
|
|
90
|
+
'prettier/prettier': ['error', {}, { usePrettierrc: true }],
|
|
91
|
+
// unused imports
|
|
92
|
+
'@typescript-eslint/no-unused-vars': 'off',
|
|
93
|
+
'unused-imports/no-unused-vars': [
|
|
94
|
+
'error',
|
|
95
|
+
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrors: 'none' },
|
|
96
|
+
],
|
|
97
|
+
'unused-imports/no-unused-imports': 'error',
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
package/eslint.config.d.ts
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { bun, bunTypeChecked } from './configs/eslint/bun.config.js';
|
|
2
|
+
import { html } from './configs/eslint/html.config.js';
|
|
3
|
+
import { json } from './configs/eslint/json.config.js';
|
|
4
|
+
import { lit } from './configs/eslint/lit.config.js';
|
|
5
|
+
import { node, nodeTypeChecked } from './configs/eslint/node.config.js';
|
|
6
|
+
import type { FlatConfig } from './configs/eslint/typescript.config.js';
|
|
7
|
+
import { setTsConfigRootDir } from './configs/eslint/typescript.config.js';
|
|
8
|
+
export { bun, bunTypeChecked, html, json, lit, node, nodeTypeChecked, setTsConfigRootDir };
|
|
9
|
+
/**
|
|
10
|
+
* Legacy all-in-one configuration, kept for backwards compatibility.
|
|
11
|
+
*
|
|
12
|
+
* Bundles the `node`, `lit`, `html` and `json` chunks and additionally wires up
|
|
13
|
+
* gitignore-based ignores plus this package's own tsconfig root — assumptions that do not
|
|
14
|
+
* hold for every consumer.
|
|
15
|
+
*
|
|
16
|
+
* Prefer a ready-made preset (`@enke.dev/lint/eslint/presets/*`) or compose the individual
|
|
17
|
+
* single configs (`@enke.dev/lint/eslint/*`) instead.
|
|
18
|
+
*
|
|
19
|
+
* @deprecated Use a preset (`frontend`, `nodeLibrary`, `bunLibrary`) or compose the single
|
|
20
|
+
* configs (`node`, `bun`, `lit`, `html`, `json`).
|
|
21
|
+
*/
|
|
22
|
+
declare const config: FlatConfig;
|
|
5
23
|
export default config;
|
package/eslint.config.js
CHANGED
|
@@ -1,21 +1,14 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from 'node:fs';
|
|
2
2
|
import { cwd } from 'node:process';
|
|
3
|
-
import { fixupPluginRules } from '@eslint/compat';
|
|
4
|
-
import eslintPluginJs from '@eslint/js';
|
|
5
|
-
import eslintPluginJson from '@eslint/json';
|
|
6
|
-
import eslintPluginHtml from '@html-eslint/eslint-plugin';
|
|
7
|
-
import eslintParserHtml from '@html-eslint/parser';
|
|
8
3
|
import { defineConfig, globalIgnores } from 'eslint/config';
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
import { configs as eslintPluginWebComponentsConfigs } from 'eslint-plugin-wc';
|
|
18
|
-
import eslintTs from 'typescript-eslint';
|
|
4
|
+
import { bun, bunTypeChecked } from './configs/eslint/bun.config.js';
|
|
5
|
+
import { html } from './configs/eslint/html.config.js';
|
|
6
|
+
import { json } from './configs/eslint/json.config.js';
|
|
7
|
+
import { lit } from './configs/eslint/lit.config.js';
|
|
8
|
+
import { node, nodeTypeChecked } from './configs/eslint/node.config.js';
|
|
9
|
+
import { setTsConfigRootDir } from './configs/eslint/typescript.config.js';
|
|
10
|
+
// re-export the individual chunks so consumers can compose their own config
|
|
11
|
+
export { bun, bunTypeChecked, html, json, lit, node, nodeTypeChecked, setTsConfigRootDir };
|
|
19
12
|
// collect gitignore excludes
|
|
20
13
|
let gitIgnoreLines = [];
|
|
21
14
|
const pathToGitIgnore = `${cwd()}/.gitignore`;
|
|
@@ -26,162 +19,25 @@ if (existsSync(pathToGitIgnore)) {
|
|
|
26
19
|
.map(line => line.trim().replace(/^\//, ''))
|
|
27
20
|
.filter(line => Boolean(line) && !line.startsWith('#'));
|
|
28
21
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Legacy all-in-one configuration, kept for backwards compatibility.
|
|
24
|
+
*
|
|
25
|
+
* Bundles the `node`, `lit`, `html` and `json` chunks and additionally wires up
|
|
26
|
+
* gitignore-based ignores plus this package's own tsconfig root — assumptions that do not
|
|
27
|
+
* hold for every consumer.
|
|
28
|
+
*
|
|
29
|
+
* Prefer a ready-made preset (`@enke.dev/lint/eslint/presets/*`) or compose the individual
|
|
30
|
+
* single configs (`@enke.dev/lint/eslint/*`) instead.
|
|
31
|
+
*
|
|
32
|
+
* @deprecated Use a preset (`frontend`, `nodeLibrary`, `bunLibrary`) or compose the single
|
|
33
|
+
* configs (`node`, `bun`, `lit`, `html`, `json`).
|
|
34
|
+
*/
|
|
37
35
|
const config = defineConfig([
|
|
38
36
|
globalIgnores([...gitIgnoreLines, 'dist/']),
|
|
39
|
-
eslintPluginPrettierRecommended,
|
|
40
37
|
setTsConfigRootDir(import.meta.dirname),
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
eslintPluginJs.configs.recommended,
|
|
46
|
-
...eslintTs.configs.strict,
|
|
47
|
-
...eslintTs.configs.stylistic,
|
|
48
|
-
eslintPluginWebComponentsConfigs['flat/recommended'],
|
|
49
|
-
eslintPluginLitConfigs['flat/recommended'],
|
|
50
|
-
eslintPluginLitA11yConfigs.recommended,
|
|
51
|
-
eslintPluginImport.flatConfigs.recommended,
|
|
52
|
-
],
|
|
53
|
-
plugins: {
|
|
54
|
-
'simple-import-sort': eslintPluginSimpleImportSort,
|
|
55
|
-
'unused-imports': eslintPluginUnusedImports,
|
|
56
|
-
'import-extensions': fixupPluginRules(eslintPluginImportExtension),
|
|
57
|
-
html: eslintPluginHtml,
|
|
58
|
-
htmlScripts: eslintPluginHtmlScripts,
|
|
59
|
-
},
|
|
60
|
-
languageOptions: { parserOptions },
|
|
61
|
-
settings: {
|
|
62
|
-
'import/resolver': {
|
|
63
|
-
typescript: {
|
|
64
|
-
bun: true,
|
|
65
|
-
node: true,
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
litHtmlSources: true,
|
|
69
|
-
},
|
|
70
|
-
rules: {
|
|
71
|
-
// formatting
|
|
72
|
-
'@typescript-eslint/no-unused-expressions': [
|
|
73
|
-
'error',
|
|
74
|
-
{ allowShortCircuit: true, allowTernary: true },
|
|
75
|
-
],
|
|
76
|
-
curly: 'error',
|
|
77
|
-
'linebreak-style': ['error', 'unix'],
|
|
78
|
-
quotes: ['error', 'single', { avoidEscape: true }],
|
|
79
|
-
semi: ['error', 'always'],
|
|
80
|
-
'no-console': 'error',
|
|
81
|
-
// inline html
|
|
82
|
-
'html/require-img-alt': 'error',
|
|
83
|
-
'html/no-multiple-h1': 'error',
|
|
84
|
-
'html/no-extra-spacing-attrs': 'error',
|
|
85
|
-
'html/no-duplicate-id': 'error',
|
|
86
|
-
'html/require-li-container': 'error',
|
|
87
|
-
'html/no-obsolete-tags': 'error',
|
|
88
|
-
'html/require-closing-tags': 'error',
|
|
89
|
-
'html/no-duplicate-attrs': 'error',
|
|
90
|
-
// import sorting
|
|
91
|
-
'simple-import-sort/imports': [
|
|
92
|
-
'error',
|
|
93
|
-
{
|
|
94
|
-
groups: [
|
|
95
|
-
// Side effect imports.
|
|
96
|
-
['^\\u0000'],
|
|
97
|
-
// Node.js builtins prefixed with `node:`.
|
|
98
|
-
['^node:'],
|
|
99
|
-
// Packages.
|
|
100
|
-
// Things that start with a letter (or digit or underscore), or `@` followed by a letter.
|
|
101
|
-
['^@?\\w'],
|
|
102
|
-
// Absolute imports and other imports such as Vue-style `@/foo`.
|
|
103
|
-
// Anything not matched in another group.
|
|
104
|
-
['^'],
|
|
105
|
-
// Relative imports.
|
|
106
|
-
// Anything that starts with a dot.
|
|
107
|
-
['^\\.'],
|
|
108
|
-
// Assetic imports, most likely inline loaded style files for lit components
|
|
109
|
-
// or raw loaded files like images, meta data or fonts.
|
|
110
|
-
['\\?(inline|raw)$'],
|
|
111
|
-
],
|
|
112
|
-
},
|
|
113
|
-
],
|
|
114
|
-
'simple-import-sort/exports': 'error',
|
|
115
|
-
// import extensions
|
|
116
|
-
'import-extensions/require-extensions': ['error', { expectedExtensions: ['js'] }],
|
|
117
|
-
'import-extensions/require-index': ['error', { expectedExtensions: ['js'] }],
|
|
118
|
-
// import rules
|
|
119
|
-
'import/enforce-node-protocol-usage': ['error', 'always'], // enforce node: import prefix
|
|
120
|
-
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'], // type imports
|
|
121
|
-
'import/first': 'error',
|
|
122
|
-
'import/newline-after-import': 'error',
|
|
123
|
-
'import/no-duplicates': 'error',
|
|
124
|
-
'import/no-unresolved': 'error',
|
|
125
|
-
'import/extensions': ['error', 'ignorePackages', { ts: 'never', js: 'always' }],
|
|
126
|
-
'prettier/prettier': ['error', {}, { usePrettierrc: true }],
|
|
127
|
-
// unused imports
|
|
128
|
-
'@typescript-eslint/no-unused-vars': 'off',
|
|
129
|
-
'unused-imports/no-unused-vars': [
|
|
130
|
-
'error',
|
|
131
|
-
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_', caughtErrors: 'none' },
|
|
132
|
-
],
|
|
133
|
-
'unused-imports/no-unused-imports': 'error',
|
|
134
|
-
// web components / a11y
|
|
135
|
-
'wc/guard-super-call': 'off',
|
|
136
|
-
},
|
|
137
|
-
},
|
|
138
|
-
// HTML files
|
|
139
|
-
{
|
|
140
|
-
files: ['**/*.html'],
|
|
141
|
-
plugins: {
|
|
142
|
-
html: eslintPluginHtml,
|
|
143
|
-
htmlScripts: eslintPluginHtmlScripts,
|
|
144
|
-
},
|
|
145
|
-
extends: ['html/recommended'],
|
|
146
|
-
language: 'html/html',
|
|
147
|
-
languageOptions: {
|
|
148
|
-
parser: eslintParserHtml,
|
|
149
|
-
parserOptions,
|
|
150
|
-
},
|
|
151
|
-
settings: {
|
|
152
|
-
'html/indent': '+2',
|
|
153
|
-
'html/lowercase': 'error',
|
|
154
|
-
'html/no-accesskey-attrs': 'error',
|
|
155
|
-
'html/no-aria-hidden-body': 'error',
|
|
156
|
-
'html/no-aria-hidden-on-focusable': 'error',
|
|
157
|
-
'html/no-duplicate-class': 'error',
|
|
158
|
-
'html/no-duplicate-in-head': 'error',
|
|
159
|
-
'html/no-empty-headings': 'error',
|
|
160
|
-
'html/no-invalid-entities': 'error',
|
|
161
|
-
'html/no-heading-inside-button': 'error',
|
|
162
|
-
'html/no-invalid-entity': 'error',
|
|
163
|
-
'html/no-invalid-role': 'error',
|
|
164
|
-
'html/no-nested-interactive': 'error',
|
|
165
|
-
'html/no-multiple-empty-lines': 'error',
|
|
166
|
-
'html/no-target-blank': 'error',
|
|
167
|
-
'html/no-trailing-spaces': 'error',
|
|
168
|
-
'html/report-bad-indent': 'error',
|
|
169
|
-
'html/require-input-label': 'error',
|
|
170
|
-
},
|
|
171
|
-
rules: {
|
|
172
|
-
'html/indent': ['error', 2],
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
// JSON files
|
|
176
|
-
{
|
|
177
|
-
files: ['**/*.json'],
|
|
178
|
-
language: 'json/json',
|
|
179
|
-
ignores: ['package-lock.json'],
|
|
180
|
-
plugins: { json: eslintPluginJson },
|
|
181
|
-
extends: [eslintPluginJson.configs.recommended],
|
|
182
|
-
rules: {
|
|
183
|
-
'json/top-level-interop': 'error',
|
|
184
|
-
},
|
|
185
|
-
},
|
|
38
|
+
...node,
|
|
39
|
+
...lit,
|
|
40
|
+
...html,
|
|
41
|
+
...json,
|
|
186
42
|
]);
|
|
187
43
|
export default config;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@enke.dev/lint",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Meta package to provide linting for web projects",
|
|
5
5
|
"homepage": "https://github.com/enke-dev/lint",
|
|
6
6
|
"repository": {
|
|
@@ -8,22 +8,62 @@
|
|
|
8
8
|
"url": "git+https://github.com/enke-dev/lint.git"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"eslint
|
|
14
|
-
"
|
|
15
|
-
"
|
|
16
|
-
"
|
|
17
|
-
"stylelint.config.js",
|
|
11
|
+
"*.config.js",
|
|
12
|
+
"*.config.d.ts",
|
|
13
|
+
"configs/eslint/*.js",
|
|
14
|
+
"configs/eslint/*.d.ts",
|
|
15
|
+
"presets/eslint/*.js",
|
|
16
|
+
"presets/eslint/*.d.ts",
|
|
18
17
|
"README.md"
|
|
19
18
|
],
|
|
20
19
|
"type": "module",
|
|
21
20
|
"main": "eslint.config.js",
|
|
22
21
|
"types": "eslint.config.d.ts",
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./eslint.config.d.ts",
|
|
25
|
+
"default": "./eslint.config.js"
|
|
26
|
+
},
|
|
27
|
+
"./eslint/node": {
|
|
28
|
+
"types": "./configs/eslint/node.config.d.ts",
|
|
29
|
+
"default": "./configs/eslint/node.config.js"
|
|
30
|
+
},
|
|
31
|
+
"./eslint/bun": {
|
|
32
|
+
"types": "./configs/eslint/bun.config.d.ts",
|
|
33
|
+
"default": "./configs/eslint/bun.config.js"
|
|
34
|
+
},
|
|
35
|
+
"./eslint/lit": {
|
|
36
|
+
"types": "./configs/eslint/lit.config.d.ts",
|
|
37
|
+
"default": "./configs/eslint/lit.config.js"
|
|
38
|
+
},
|
|
39
|
+
"./eslint/html": {
|
|
40
|
+
"types": "./configs/eslint/html.config.d.ts",
|
|
41
|
+
"default": "./configs/eslint/html.config.js"
|
|
42
|
+
},
|
|
43
|
+
"./eslint/json": {
|
|
44
|
+
"types": "./configs/eslint/json.config.d.ts",
|
|
45
|
+
"default": "./configs/eslint/json.config.js"
|
|
46
|
+
},
|
|
47
|
+
"./eslint/presets/frontend": {
|
|
48
|
+
"types": "./presets/eslint/frontend.preset.d.ts",
|
|
49
|
+
"default": "./presets/eslint/frontend.preset.js"
|
|
50
|
+
},
|
|
51
|
+
"./eslint/presets/node-library": {
|
|
52
|
+
"types": "./presets/eslint/node-library.preset.d.ts",
|
|
53
|
+
"default": "./presets/eslint/node-library.preset.js"
|
|
54
|
+
},
|
|
55
|
+
"./eslint/presets/bun-library": {
|
|
56
|
+
"types": "./presets/eslint/bun-library.preset.d.ts",
|
|
57
|
+
"default": "./presets/eslint/bun-library.preset.js"
|
|
58
|
+
},
|
|
59
|
+
"./*": "./*"
|
|
60
|
+
},
|
|
23
61
|
"scripts": {
|
|
24
62
|
"check": "tsc -p tsconfig.build.json --noEmit",
|
|
25
63
|
"lint": "eslint -c test.eslint.config.ts .",
|
|
26
|
-
"test": "
|
|
64
|
+
"test": "run-p -ns test:*",
|
|
65
|
+
"test:node": "node --experimental-strip-types --test test.run.node.ts",
|
|
66
|
+
"test:bun": "bun test ./test.run.bun.ts",
|
|
27
67
|
"inspect": "eslint-config-inspector --config eslint.config.ts",
|
|
28
68
|
"dev": "tsc -p tsconfig.build.json --watch",
|
|
29
69
|
"build": "tsc -p tsconfig.build.json"
|
|
@@ -42,8 +82,8 @@
|
|
|
42
82
|
},
|
|
43
83
|
"peerDependencies": {
|
|
44
84
|
"@awmottaz/prettier-plugin-void-html": "^2.1.0",
|
|
45
|
-
"eslint": "^10.
|
|
46
|
-
"prettier": "^3.9.
|
|
85
|
+
"eslint": "^10.7.0",
|
|
86
|
+
"prettier": "^3.9.5"
|
|
47
87
|
},
|
|
48
88
|
"optionalDependencies": {
|
|
49
89
|
"jiti": "^2.7.0",
|
|
@@ -52,14 +92,14 @@
|
|
|
52
92
|
"stylelint-config-standard-scss": "^17.0.0",
|
|
53
93
|
"stylelint-order": "^8.1.1",
|
|
54
94
|
"typescript": "^6.0.3",
|
|
55
|
-
"typescript-eslint": "^8.
|
|
95
|
+
"typescript-eslint": "^8.63.0"
|
|
56
96
|
},
|
|
57
97
|
"dependencies": {
|
|
58
98
|
"@eslint/compat": "2.1.0",
|
|
59
99
|
"@eslint/js": "10.0.1",
|
|
60
100
|
"@eslint/json": "2.0.1",
|
|
61
|
-
"@html-eslint/eslint-plugin": "0.
|
|
62
|
-
"@html-eslint/parser": "0.
|
|
101
|
+
"@html-eslint/eslint-plugin": "0.64.0",
|
|
102
|
+
"@html-eslint/parser": "0.64.0",
|
|
63
103
|
"eslint-config-prettier": "10.1.8",
|
|
64
104
|
"eslint-import-resolver-typescript": "4.4.5",
|
|
65
105
|
"eslint-plugin-html": "8.1.4",
|
|
@@ -76,15 +116,16 @@
|
|
|
76
116
|
"devDependencies": {
|
|
77
117
|
"@awmottaz/prettier-plugin-void-html": "2.1.0",
|
|
78
118
|
"@eslint/config-inspector": "3.0.4",
|
|
79
|
-
"@types/node": "24.13.
|
|
80
|
-
"eslint": "10.
|
|
119
|
+
"@types/node": "24.13.3",
|
|
120
|
+
"eslint": "10.7.0",
|
|
81
121
|
"jiti": "2.7.0",
|
|
82
|
-
"
|
|
122
|
+
"npm-run-all2": "9.0.2",
|
|
123
|
+
"prettier": "3.9.5",
|
|
83
124
|
"stylelint": "17.14.0",
|
|
84
125
|
"stylelint-config-rational-order": "0.1.2",
|
|
85
126
|
"stylelint-config-standard-scss": "17.0.0",
|
|
86
127
|
"stylelint-order": "8.1.1",
|
|
87
128
|
"typescript": "6.0.3",
|
|
88
|
-
"typescript-eslint": "8.
|
|
129
|
+
"typescript-eslint": "8.63.0"
|
|
89
130
|
}
|
|
90
131
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
import { bun, bunTypeChecked } from '../../configs/eslint/bun.config.js';
|
|
3
|
+
import { json } from '../../configs/eslint/json.config.js';
|
|
4
|
+
// Bun library: same as the node library but with the bun module resolver so builtins
|
|
5
|
+
// such as `bun:test` and `bun:sqlite` resolve instead of being flagged as unresolved.
|
|
6
|
+
export const bunLibrary = defineConfig([...bun, ...json]);
|
|
7
|
+
// Same as `bunLibrary`, plus type-aware rules (needs a tsconfig; see `TypescriptOptions`).
|
|
8
|
+
export const bunLibraryTypeChecked = defineConfig([...bunTypeChecked, ...json]);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
import { html } from '../../configs/eslint/html.config.js';
|
|
3
|
+
import { json } from '../../configs/eslint/json.config.js';
|
|
4
|
+
import { lit } from '../../configs/eslint/lit.config.js';
|
|
5
|
+
import { node, nodeTypeChecked } from '../../configs/eslint/node.config.js';
|
|
6
|
+
// Frontend projects: TypeScript/JavaScript with web components (lit), inline and
|
|
7
|
+
// standalone HTML, and JSON. Bundled/emitted via tsc, so node-style `.js` import
|
|
8
|
+
// extensions and the node resolver.
|
|
9
|
+
export const frontend = defineConfig([...node, ...lit, ...html, ...json]);
|
|
10
|
+
// Same as `frontend`, plus type-aware rules (needs a tsconfig; see `TypescriptOptions`).
|
|
11
|
+
export const frontendTypeChecked = defineConfig([
|
|
12
|
+
...nodeTypeChecked,
|
|
13
|
+
...lit,
|
|
14
|
+
...html,
|
|
15
|
+
...json,
|
|
16
|
+
]);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { defineConfig } from 'eslint/config';
|
|
2
|
+
import { json } from '../../configs/eslint/json.config.js';
|
|
3
|
+
import { node, nodeTypeChecked } from '../../configs/eslint/node.config.js';
|
|
4
|
+
// Node library: TypeScript/JavaScript emitted via tsc plus JSON. No web components or
|
|
5
|
+
// standalone HTML.
|
|
6
|
+
export const nodeLibrary = defineConfig([...node, ...json]);
|
|
7
|
+
// Same as `nodeLibrary`, plus type-aware rules (needs a tsconfig; see `TypescriptOptions`).
|
|
8
|
+
export const nodeLibraryTypeChecked = defineConfig([...nodeTypeChecked, ...json]);
|