@scayle/eslint-config-storefront 4.8.3-alpha.1 → 5.1.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/CHANGELOG.md +117 -0
- package/README.md +126 -43
- package/config/ignores.mjs +46 -0
- package/config/index.mjs +129 -0
- package/config/javascript.mjs +159 -0
- package/config/rules.mjs +220 -0
- package/config/test.mjs +36 -0
- package/config/typescript.mjs +92 -0
- package/config/unicorn.mjs +33 -0
- package/config/v3/importResolver.mjs +71 -0
- package/config/v3/storybook.mjs +10 -0
- package/config/v3/tailwind.mjs +30 -0
- package/config/v3/vue.mjs +153 -0
- package/config/v3/vueComposable.mjs +29 -0
- package/config/v3/vueI18n.mjs +52 -0
- package/config/v3.mjs +66 -0
- package/config/v3.test.mjs +128 -0
- package/index.mjs +3 -2
- package/package.json +37 -17
- package/storefront-nuxt.mjs +4 -0
- package/storefront-v3.mjs +4 -0
- package/config/flat/importX.mjs +0 -22
- package/config/flat/index.mjs +0 -155
- package/config/flat/promise.mjs +0 -28
- package/config/flat/sonarjs.mjs +0 -19
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,122 @@
|
|
|
1
1
|
# @aboutyou/eslint-config-sfc
|
|
2
2
|
|
|
3
|
+
## 5.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- `@scayle/eslint-config-storefront/v3` now wires an `eslint-import-resolver-typescript` resolver by default, pointed at the project's `tsconfig.json`. Path aliases like `@client/*` or `@server/*` resolve to real files, so `import-x/no-restricted-paths` and `import-x/no-cycle` see through them instead of only matching literal relative imports.
|
|
8
|
+
|
|
9
|
+
Two rules also newly cover ground they didn't before, both enabled for the first time rather than tightened:
|
|
10
|
+
|
|
11
|
+
- `import-x/order` wasn't configured anywhere in `/v3` until now. It ships at `error`, with an explicit `groups` option ranking aliased imports alongside package imports, ahead of relative ones. A project already using `/v3` may see new ordering errors on upgrade.
|
|
12
|
+
- `import-x/no-cycle` previously only saw `.js`/`.mjs`/`.cjs` files. `.ts` and `.tsx` are now included, so a circular dependency that only existed between TypeScript files, alias or not, is caught for the first time.
|
|
13
|
+
|
|
14
|
+
`resolver.tsconfigPath` points the resolver at a specific tsconfig, independent of `typescript.tsconfigPath` (which also switches on type-aware TypeScript rules). Without either set, the resolver and the `no-restricted-paths` zones fall back to resolving relative to ESLint's working directory, correct when linting runs via `pnpm lint`/CI but not guaranteed for an editor's ESLint extension. Set `resolver.tsconfigPath` to an absolute path if that matters for your setup.
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Added dependency `eslint-import-resolver-typescript@^4.4.5`
|
|
19
|
+
|
|
20
|
+
## 5.0.0
|
|
21
|
+
|
|
22
|
+
### Major Changes
|
|
23
|
+
|
|
24
|
+
- Rebuilds the shared ESLint config directly on first-class plugins (`@eslint/js`, `typescript-eslint`, `eslint-plugin-n`, `eslint-plugin-jsonc`, `eslint-plugin-jsdoc`, `eslint-plugin-unicorn`, `eslint-plugin-regexp`, `@e18e/eslint-plugin`, `@eslint-community/eslint-plugin-eslint-comments`, `@vitest/eslint-plugin`) instead of wrapping `@antfu/eslint-config`. This drops the transitive dependency on framework-specific plugins (Vue, React, Astro, and others) this package never used, and makes every enabled rule visible directly in `config/`.
|
|
25
|
+
|
|
26
|
+
## Breaking changes
|
|
27
|
+
- `eslintConfigStorefront({ isNuxt: true })` is replaced by a dedicated entry point: `import eslintConfigStorefrontNuxt from '@scayle/eslint-config-storefront/nuxt'`. `eslintConfigStorefront()` no longer accepts an `isNuxt` option. It always applies the framework-agnostic and JavaScript/TypeScript/JSDoc rule set.
|
|
28
|
+
- Rules keep each plugin's own published name instead of antfu's renamed aliases: `@typescript-eslint/*` (not `ts/*`), `vitest/*` (not `test/*` for Vitest-specific rules; `no-only-tests/*` is unchanged). Update any inline `eslint-disable` comment that references the old alias.
|
|
29
|
+
- `config/flat/` moved to `config/`. Flat config is the only supported mode, so the `flat/` segment was redundant. If your project imported anything from `@scayle/eslint-config-storefront/config/flat/*` directly, update the import path.
|
|
30
|
+
- `@typescript-eslint/consistent-type-imports` now allows `import('mod').Type` inline type annotations (`disallowTypeAnnotations: false`), matching common TypeScript usage the previous rule severity silently never reached under the old rule composition.
|
|
31
|
+
- The `eslint` peer dependency floor moves from `>=9.0.0` to `>=10.4.0`, matching what `eslint-plugin-unicorn@73` actually requires. An ESLint 9 project installed this package cleanly before but hit unmet peer warnings from the plugins themselves. Upgrade ESLint to 10.4 or later before upgrading this package.
|
|
32
|
+
|
|
33
|
+
## New rule sets
|
|
34
|
+
|
|
35
|
+
Three additions widen the default coverage. Each is on by default in both `eslintConfigStorefront()` and `eslintConfigStorefrontNuxt()`, and each can surface new findings in an existing project on upgrade:
|
|
36
|
+
|
|
37
|
+
- **`eslint-plugin-unicorn`**: a curated subset of modernization rules (not the plugin's full `recommended` preset, which is hundreds of rules and largely stylistic). Covers things like preferring `node:`-prefixed core imports, `Array.isArray` over `instanceof Array`, and `Number.isNaN` over the global `isNaN`.
|
|
38
|
+
- **`eslint-plugin-regexp`**: the plugin's own `flat/recommended` preset. Flags unsafe or redundant regex patterns, including some that can cause catastrophic backtracking.
|
|
39
|
+
- **`@e18e/eslint-plugin`**: the [e18e](https://e18e.dev) community's `recommended` preset (modernization, module-replacement, and performance rules), with every rule downgraded to `warn`. The plugin is pre-1.0, and its rule set hasn't been reviewed against every consuming project yet, so findings surface without failing CI. Includes `ban-dependencies`, which flags known heavier packages with a lighter recommended alternative (for example `ora` in favor of `nanospinner`). Treat a `ban-dependencies` finding as a suggestion to evaluate, not a required change: swapping a dependency is a real decision with its own testing burden, not a lint fix.
|
|
40
|
+
|
|
41
|
+
## Upgrading
|
|
42
|
+
1. Run `eslint .` after upgrading. Fix or explicitly suppress any new finding before merging.
|
|
43
|
+
2. If your project used `eslintConfigStorefront({ isNuxt: true })`, switch to the `/nuxt` entry point:
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
// Before
|
|
47
|
+
import eslintConfigStorefront from '@scayle/eslint-config-storefront'
|
|
48
|
+
export default eslintConfigStorefront({ isNuxt: true })
|
|
49
|
+
|
|
50
|
+
// After
|
|
51
|
+
import eslintConfigStorefrontNuxt from '@scayle/eslint-config-storefront/nuxt'
|
|
52
|
+
export default eslintConfigStorefrontNuxt()
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
3. Search your project for any inline rule reference using an antfu alias (`ts/`, `test/` for Vitest rules) and update it to the plugin's real prefix (`@typescript-eslint/`, `vitest/`).
|
|
56
|
+
|
|
57
|
+
- Adds `@scayle/eslint-config-storefront/v3`, a third entry point for the Storefront Application V3 stack (Hono, Inertia.js, Vue 3, not Nuxt). It builds on the default config and adds Vue language wiring, Vue rules, accessibility rules, `vue-i18n` linting, `@scayle/vue-composable` rules, Storybook file conventions, Tailwind CSS class validation, and `vue/block-order` enforcement.
|
|
58
|
+
|
|
59
|
+
## Breaking changes
|
|
60
|
+
- The named exports `eslintConfigStorefront` and `eslintConfigStorefrontNuxt` are now `storefront` and `storefrontNuxt`. Neither name, nor the `./nuxt` entry point itself, shipped in a published release before this change, so this only affects code already on this pre-release. Default exports are unaffected:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
// Before
|
|
64
|
+
import { eslintConfigStorefront } from '@scayle/eslint-config-storefront'
|
|
65
|
+
|
|
66
|
+
// After
|
|
67
|
+
import { storefront } from '@scayle/eslint-config-storefront'
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
- `vue/block-order` is now enforced at error severity on `./v3`, with `template` before `script` before `style`. `eslint-plugin-vue`'s own `recommended` default only warns and defaults to script-first. Any `.vue` file with a script or style block ahead of its template now fails lint. Run `eslint --fix` to reorder them; the fix is purely mechanical and doesn't change behavior.
|
|
71
|
+
|
|
72
|
+
## New entry point
|
|
73
|
+
|
|
74
|
+
`@scayle/eslint-config-storefront/v3` takes required `tailwind.entryPoint` and `i18n.localeDir` options, since the underlying plugins can't validate Tailwind classes or i18n keys without a real path. Optional options cover a shop's own custom elements, dynamically-used i18n keys, and fallthrough-attribute exceptions:
|
|
75
|
+
|
|
76
|
+
```js
|
|
77
|
+
// eslint.config.mjs
|
|
78
|
+
import storefrontV3 from '@scayle/eslint-config-storefront/v3'
|
|
79
|
+
|
|
80
|
+
export default storefrontV3({
|
|
81
|
+
tailwind: {
|
|
82
|
+
entryPoint: './src/client/index.css',
|
|
83
|
+
},
|
|
84
|
+
i18n: {
|
|
85
|
+
localeDir: './src/i18n/locales/*.json',
|
|
86
|
+
},
|
|
87
|
+
})
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Named `v3`, not `vue`, since a future non-Vue Storefront Application V3 stack would extend this same entry point rather than needing a separate one.
|
|
91
|
+
|
|
92
|
+
### Patch Changes
|
|
93
|
+
|
|
94
|
+
- Added dependency `@e18e/eslint-plugin@^0.8.0`
|
|
95
|
+
- Added dependency `@eslint-community/eslint-plugin-eslint-comments@^4.7.2`
|
|
96
|
+
- Added dependency `@eslint/js@^10.0.0`
|
|
97
|
+
- Added dependency `@intlify/eslint-plugin-vue-i18n@^4.5.1`
|
|
98
|
+
- Added dependency `@scayle/eslint-plugin-vue-composable@workspace:*`
|
|
99
|
+
- Added dependency `@vitest/eslint-plugin@^1.6.20`
|
|
100
|
+
- Added dependency `eslint-plugin-better-tailwindcss@^4.7.0`
|
|
101
|
+
- Added dependency `eslint-plugin-jsdoc@^64.2.1`
|
|
102
|
+
- Added dependency `eslint-plugin-jsonc@^3.4.1`
|
|
103
|
+
- Added dependency `eslint-plugin-n@^18.3.0`
|
|
104
|
+
- Added dependency `eslint-plugin-no-only-tests@^3.4.0`
|
|
105
|
+
- Added dependency `eslint-plugin-regexp@^3.2.0`
|
|
106
|
+
- Added dependency `eslint-plugin-storybook@^10.5.8`
|
|
107
|
+
- Added dependency `eslint-plugin-unicorn@^73.0.0`
|
|
108
|
+
- Added dependency `eslint-plugin-vue@^10.10.0`
|
|
109
|
+
- Added dependency `eslint-plugin-vuejs-accessibility@^2.6.0`
|
|
110
|
+
- Added dependency `globals@^17.7.0`
|
|
111
|
+
- Added dependency `vue-eslint-parser@^10.4.1`
|
|
112
|
+
- Removed dependency `@antfu/eslint-config@^9.0.0`
|
|
113
|
+
- Removed dependency `@eslint/eslintrc@^3.3.5`
|
|
114
|
+
- Removed dependency `local-pkg@^1.2.1`
|
|
115
|
+
- Updated dependency `eslint-config-flat-gitignore@^2.2.0` to `eslint-config-flat-gitignore@^2.3.0`
|
|
116
|
+
- Updated dependency `eslint-plugin-import-x@^4.16.2` to `eslint-plugin-import-x@^4.17.1`
|
|
117
|
+
- Updated dependency `eslint-plugin-sonarjs@^4.0.3` to `eslint-plugin-sonarjs@^4.2.0`
|
|
118
|
+
- Updated dependency `typescript-eslint@8.67.0` to `typescript-eslint@^8.67.0`
|
|
119
|
+
|
|
3
120
|
## 4.8.3-alpha.1
|
|
4
121
|
|
|
5
122
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -3,11 +3,10 @@
|
|
|
3
3
|
A [shared `eslint` config](https://eslint.org/docs/latest/extend/shareable-configs#creating-a-shareable-config) for SCAYLE Storefront projects and packages.
|
|
4
4
|
Provides SCAYLE-specific `eslint` configuration for Frontend and Node.js projects using TypeScript.
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
Flat config only ([ESLint 10.4+](https://eslint.org/docs/latest/use/configure/configuration-files)). Built directly on first-class plugins (`@eslint/js`, `typescript-eslint`, `eslint-plugin-n`, `eslint-plugin-jsonc`, `eslint-plugin-jsdoc`, `eslint-plugin-unicorn`, `eslint-plugin-regexp`, `@e18e/eslint-plugin`, and others) with no shared-config aggregator dependency.
|
|
7
7
|
|
|
8
8
|
Should you require support for `eslint@8`, please use `@scayle/eslint-config-storefront@3`.
|
|
9
9
|
|
|
10
|
-
- Partially based on [@antfu/eslint-config](https://github.com/antfu/eslint-config)
|
|
11
10
|
- [Official ESLint Documentation](https://eslint.org/docs/latest/)
|
|
12
11
|
|
|
13
12
|
---
|
|
@@ -24,11 +23,86 @@ And create a `eslint.config.mjs` in your project root:
|
|
|
24
23
|
|
|
25
24
|
```js
|
|
26
25
|
// eslint.config.mjs
|
|
27
|
-
import
|
|
26
|
+
import storefront from '@scayle/eslint-config-storefront'
|
|
28
27
|
|
|
29
|
-
export default
|
|
28
|
+
export default storefront()
|
|
30
29
|
```
|
|
31
30
|
|
|
31
|
+
### Nuxt projects
|
|
32
|
+
|
|
33
|
+
Nuxt projects already get JavaScript, TypeScript, JSDoc, and import rules from
|
|
34
|
+
[`@nuxt/eslint`](https://eslint.nuxt.com/). Use the `/nuxt` entry point instead, which
|
|
35
|
+
only adds the framework-agnostic rules (comments hygiene, Node.js, JSON/JSONC, test-file
|
|
36
|
+
conventions, SonarJS, Promise usage, modernization, and regex safety):
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
// eslint.config.mjs
|
|
40
|
+
import storefrontNuxt from '@scayle/eslint-config-storefront/nuxt'
|
|
41
|
+
import withNuxt from './.nuxt/eslint.config.mjs'
|
|
42
|
+
|
|
43
|
+
export default withNuxt(storefrontNuxt())
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Storefront Application V3 projects
|
|
47
|
+
|
|
48
|
+
The Storefront Application V3 stack (Hono + Inertia.js + Vue 3, not Nuxt) should use the
|
|
49
|
+
`/v3` entry point. It builds on the default config and adds Vue language wiring, Vue rules,
|
|
50
|
+
accessibility rules, `vue-i18n` linting, `@scayle/vue-composable` rules, Storybook file
|
|
51
|
+
conventions, Tailwind CSS class validation, and a TypeScript-aware import resolver:
|
|
52
|
+
|
|
53
|
+
```js
|
|
54
|
+
// eslint.config.mjs
|
|
55
|
+
import storefrontV3 from '@scayle/eslint-config-storefront/v3'
|
|
56
|
+
|
|
57
|
+
export default storefrontV3({
|
|
58
|
+
tailwind: {
|
|
59
|
+
entryPoint: './src/client/index.css',
|
|
60
|
+
},
|
|
61
|
+
i18n: {
|
|
62
|
+
localeDir: './src/i18n/locales/*.json',
|
|
63
|
+
},
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`tailwind.entryPoint` and `i18n.localeDir` are required, the underlying plugins can't
|
|
68
|
+
validate Tailwind classes or i18n keys without a real path. Optional options:
|
|
69
|
+
|
|
70
|
+
- `typescript.tsconfigPath`: absolute path to a `tsconfig.json`. Enables type-aware
|
|
71
|
+
TypeScript rules and points the import resolver at that file instead of
|
|
72
|
+
`<root>/tsconfig.json`
|
|
73
|
+
- `resolver.tsconfigPath`: absolute path to a `tsconfig.json` for the import resolver only,
|
|
74
|
+
independent of `typescript.tsconfigPath`. Use this instead when you want the resolver
|
|
75
|
+
fix below without also switching on type-aware TypeScript rules
|
|
76
|
+
- `i18n.messageSyntaxVersion`: `vue-i18n` message syntax version, defaults to `^11.2.8`
|
|
77
|
+
- `i18n.unusedKeyIgnores`: regex-string patterns for translation keys used dynamically in code
|
|
78
|
+
- `vue.undefComponentIgnores`: custom element (web component) tag names to exempt from `vue/no-undef-components`
|
|
79
|
+
- `vueComposable.fallthroughAttrsIgnores`: path fragments to exempt from `require-explicit-fallthrough-attrs` (e.g. router-mounted page/layout roots that never receive fallthrough attributes)
|
|
80
|
+
|
|
81
|
+
#### Import resolution
|
|
82
|
+
|
|
83
|
+
`/v3` wires `eslint-import-resolver-typescript`, so `import-x` rules resolve `tsconfig.json`
|
|
84
|
+
path aliases (`@client/*`, `@server/*`, or any other `paths` entry) to their real files
|
|
85
|
+
instead of only matching literal relative imports. Three rules depend on that resolution
|
|
86
|
+
to work correctly against an aliased import:
|
|
87
|
+
|
|
88
|
+
- `import-x/no-restricted-paths`: zone violations across an alias fail lint, not just
|
|
89
|
+
across a relative path
|
|
90
|
+
- `import-x/no-cycle`: circular dependencies through an aliased import are caught. `.vue`
|
|
91
|
+
files are the one exception, a cycle through a `.vue` file only surfaces when ESLint
|
|
92
|
+
lints that file directly
|
|
93
|
+
- `import-x/order`: aliased imports rank alongside package imports (`external`), ahead of
|
|
94
|
+
relative ones, instead of dropping to last place once the resolver can see they resolve
|
|
95
|
+
to a project file
|
|
96
|
+
|
|
97
|
+
Without `resolver.tsconfigPath` or `typescript.tsconfigPath` set, both the resolver and
|
|
98
|
+
`import-x/no-restricted-paths`'s zones resolve relative to ESLint's own working directory.
|
|
99
|
+
That's correct for `pnpm lint` and CI, since a monorepo's task runner always runs a
|
|
100
|
+
package's lint script with that package as the working directory, but not guaranteed for
|
|
101
|
+
an editor's ESLint extension, which can run with the workspace root as its working
|
|
102
|
+
directory instead. Set `resolver.tsconfigPath` to an absolute path (for example,
|
|
103
|
+
`new URL('./tsconfig.json', import.meta.url).pathname` in your `eslint.config.mjs`) if your
|
|
104
|
+
editor's linting needs to match the command-line result.
|
|
105
|
+
|
|
32
106
|
### Add script for package.json
|
|
33
107
|
|
|
34
108
|
For example:
|
|
@@ -77,66 +151,75 @@ Add the following settings to your `.vscode/settings.json`:
|
|
|
77
151
|
|
|
78
152
|
## Customization
|
|
79
153
|
|
|
80
|
-
###
|
|
81
|
-
|
|
82
|
-
#### Default config / `@scayle/eslint-config-storefront`
|
|
83
|
-
|
|
84
|
-
Normally you only need to import the antfu preset:
|
|
154
|
+
### Default config / `@scayle/eslint-config-storefront`
|
|
85
155
|
|
|
86
156
|
```js
|
|
87
157
|
// eslint.config.mjs
|
|
88
|
-
import
|
|
158
|
+
import storefront from '@scayle/eslint-config-storefront'
|
|
89
159
|
|
|
90
|
-
export default
|
|
160
|
+
export default storefront({
|
|
161
|
+
typescript: {
|
|
162
|
+
// Enables type-aware rules for the given tsconfig
|
|
163
|
+
tsconfigPath: 'path/to/tsconfig.json',
|
|
164
|
+
},
|
|
165
|
+
})
|
|
91
166
|
```
|
|
92
167
|
|
|
93
|
-
###
|
|
168
|
+
### Nuxt config / `@scayle/eslint-config-storefront/nuxt`
|
|
94
169
|
|
|
95
170
|
```js
|
|
96
171
|
// eslint.config.mjs
|
|
97
|
-
import
|
|
172
|
+
import storefrontNuxt from '@scayle/eslint-config-storefront/nuxt'
|
|
98
173
|
|
|
99
|
-
export default
|
|
100
|
-
|
|
101
|
-
// that are provided by the `@nuxt/eslint` package
|
|
102
|
-
isNuxt: true, // Default via auto-detection of package `@nuxt/eslint`
|
|
174
|
+
export default storefrontNuxt()
|
|
175
|
+
```
|
|
103
176
|
|
|
104
|
-
|
|
105
|
-
isTailwind: true, // Default via auto-detection of package `eslint-plugin-tailwind`
|
|
177
|
+
### Storefront Application V3 config / `@scayle/eslint-config-storefront/v3`
|
|
106
178
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
```
|
|
179
|
+
See [Storefront Application V3 projects](#storefront-application-v3-projects) above for the full option list.
|
|
180
|
+
|
|
181
|
+
All three entry points return a [`FlatConfigComposer`](https://github.com/antfu/eslint-flat-config-utils),
|
|
182
|
+
so you can chain `.append(...)`, `.prepend(...)`, `.override(...)`, or `.renamePlugins(...)` to layer
|
|
183
|
+
project-specific rules on top.
|
|
184
|
+
|
|
185
|
+
### Plugin names
|
|
115
186
|
|
|
116
|
-
|
|
187
|
+
Rules use each plugin's own published name (`@typescript-eslint/*`, `import-x/*`, `jsonc/*`,
|
|
188
|
+
`jsdoc/*`, `node/*`, `promise/*`, `sonarjs/*`, `unicorn/*`, `regexp/*`, `e18e/*`, `vitest/*`,
|
|
189
|
+
`eslint-comments/*`). There's no alias renaming. When you override or disable a rule inline,
|
|
190
|
+
use that plugin's real prefix:
|
|
117
191
|
|
|
118
|
-
|
|
192
|
+
```js
|
|
193
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-definitions
|
|
194
|
+
type Foo = { bar: 2 }
|
|
195
|
+
```
|
|
119
196
|
|
|
120
|
-
|
|
121
|
-
| ---------- | ---------------------- | ------------------------------------------------------------------------------------------ |
|
|
122
|
-
| `import/*` | `import-x/*` | [eslint-plugin-import-x](https://github.com/un-es/eslint-plugin-import-x) |
|
|
123
|
-
| `node/*` | `n/*` | [eslint-plugin-n](https://github.com/eslint-community/eslint-plugin-n) |
|
|
124
|
-
| `yaml/*` | `yml/*` | [eslint-plugin-yml](https://github.com/ota-meshi/eslint-plugin-yml) |
|
|
125
|
-
| `ts/*` | `@typescript-eslint/*` | [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint) |
|
|
126
|
-
| `test/*` | `vitest/*` | [eslint-plugin-vitest](https://github.com/veritem/eslint-plugin-vitest) |
|
|
127
|
-
| `test/*` | `no-only-tests/*` | [eslint-plugin-no-only-tests](https://github.com/levibuzolic/eslint-plugin-no-only-tests) |
|
|
197
|
+
### `e18e/*` rules ship as warnings
|
|
128
198
|
|
|
129
|
-
|
|
199
|
+
The [e18e](https://e18e.dev) community's rule set (modernization, module-replacement, and
|
|
200
|
+
performance rules) is enabled by default, but every `e18e/*` rule ships at `warn`, not `error`.
|
|
201
|
+
The plugin is still pre-1.0, and its rule set hasn't been reviewed against every consuming
|
|
202
|
+
project. A warning won't fail your build.
|
|
130
203
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
204
|
+
One rule worth knowing about specifically: `e18e/ban-dependencies` flags a dependency in your
|
|
205
|
+
project that has a lighter recommended alternative (for example `ora` in favor of
|
|
206
|
+
`nanospinner`). Treat that finding as something to evaluate, not something to fix immediately.
|
|
207
|
+
Swapping a dependency is a real decision with its own testing cost, not a lint fix. If you've
|
|
208
|
+
decided to keep a flagged dependency, allowlist it explicitly rather than turning the rule off:
|
|
209
|
+
|
|
210
|
+
```js
|
|
211
|
+
export default storefront().append({
|
|
212
|
+
rules: {
|
|
213
|
+
'e18e/ban-dependencies': ['warn', { allowed: ['ora'] }],
|
|
214
|
+
},
|
|
215
|
+
})
|
|
135
216
|
```
|
|
136
217
|
|
|
137
218
|
## View what rules are enabled
|
|
138
219
|
|
|
139
|
-
[
|
|
220
|
+
[@eslint/config-inspector](https://github.com/eslint/config-inspector) is a visual tool maintained
|
|
221
|
+
by the ESLint core team to help you view what rules are enabled in your project and which files
|
|
222
|
+
they apply to.
|
|
140
223
|
|
|
141
224
|
Go into your project root that contains eslint.config.js and run:
|
|
142
225
|
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// Build artifacts, lockfiles, and tooling caches that no project should lint.
|
|
2
|
+
export const GLOB_EXCLUDE = [
|
|
3
|
+
'**/node_modules',
|
|
4
|
+
'**/dist',
|
|
5
|
+
'**/package-lock.json',
|
|
6
|
+
'**/yarn.lock',
|
|
7
|
+
'**/pnpm-lock.yaml',
|
|
8
|
+
'**/bun.lockb',
|
|
9
|
+
'**/output',
|
|
10
|
+
'**/coverage',
|
|
11
|
+
'**/playwright-report',
|
|
12
|
+
'**/test-results',
|
|
13
|
+
'**/temp',
|
|
14
|
+
'**/.temp',
|
|
15
|
+
'**/tmp',
|
|
16
|
+
'**/.tmp',
|
|
17
|
+
'**/.history',
|
|
18
|
+
'**/.vitepress/cache',
|
|
19
|
+
'**/.nuxt',
|
|
20
|
+
'**/.next',
|
|
21
|
+
'**/.svelte-kit',
|
|
22
|
+
'**/.vercel',
|
|
23
|
+
'**/.changeset',
|
|
24
|
+
'**/.idea',
|
|
25
|
+
'**/.cache',
|
|
26
|
+
'**/.output',
|
|
27
|
+
'**/.vite-inspect',
|
|
28
|
+
'**/.yarn',
|
|
29
|
+
'**/CHANGELOG*.md',
|
|
30
|
+
'**/LICENSE*',
|
|
31
|
+
'**/*.min.*',
|
|
32
|
+
'**/__snapshots__',
|
|
33
|
+
'**/vite.config.*.timestamp-*',
|
|
34
|
+
'**/auto-import?(s).d.ts',
|
|
35
|
+
'**/components.d.ts',
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
/** @returns {import('eslint').Linter.Config[]} Flat config entries excluding build artifacts and tooling caches from linting. */
|
|
39
|
+
export function ignoresConfig() {
|
|
40
|
+
return [
|
|
41
|
+
{
|
|
42
|
+
name: 'storefront/ignores',
|
|
43
|
+
ignores: GLOB_EXCLUDE,
|
|
44
|
+
},
|
|
45
|
+
]
|
|
46
|
+
}
|
package/config/index.mjs
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { FlatConfigComposer } from 'eslint-flat-config-utils'
|
|
2
|
+
import gitignore from 'eslint-config-flat-gitignore'
|
|
3
|
+
import {
|
|
4
|
+
commentsConfig,
|
|
5
|
+
nodeConfig,
|
|
6
|
+
jsoncConfig,
|
|
7
|
+
sonarjsConfig,
|
|
8
|
+
promiseConfig,
|
|
9
|
+
importXConfig,
|
|
10
|
+
jsdocConfig,
|
|
11
|
+
regexpConfig,
|
|
12
|
+
e18eConfig,
|
|
13
|
+
} from './rules.mjs'
|
|
14
|
+
import { testConfig, GLOB_TESTS } from './test.mjs'
|
|
15
|
+
import { ignoresConfig } from './ignores.mjs'
|
|
16
|
+
import { javascriptConfig } from './javascript.mjs'
|
|
17
|
+
import { typescriptConfig } from './typescript.mjs'
|
|
18
|
+
import { unicornConfig } from './unicorn.mjs'
|
|
19
|
+
|
|
20
|
+
/** @type {import('eslint').Linter.RuleEntry} */
|
|
21
|
+
const CURLY_RULE = ['error', 'all']
|
|
22
|
+
|
|
23
|
+
/** @type {import('eslint').Linter.RulesRecord} */
|
|
24
|
+
const GLOBAL_RULES = {
|
|
25
|
+
curly: CURLY_RULE,
|
|
26
|
+
'node/prefer-global/process': 'off',
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** @type {import('eslint').Linter.RulesRecord} */
|
|
30
|
+
const TEST_RULES = {
|
|
31
|
+
'no-console': 'off',
|
|
32
|
+
'@typescript-eslint/no-explicit-any': 'off',
|
|
33
|
+
'promise/avoid-new': 'off',
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const IGNORE_PATTERNS = ['**/fixtures/**/*', '**/*.jsonc']
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @typedef {object} EslintConfigStorefrontOptions
|
|
40
|
+
* @property {object} [typescript] Options forwarded to `typescriptConfig`.
|
|
41
|
+
* @property {string} [typescript.tsconfigPath] Enables type-aware TypeScript rules when set.
|
|
42
|
+
*/
|
|
43
|
+
|
|
44
|
+
// Rules shared by every project regardless of framework: comments hygiene, Node.js,
|
|
45
|
+
// JSON/JSONC, test-file conventions, SonarJS, Promise usage, modernization (unicorn,
|
|
46
|
+
// e18e), and regex safety.
|
|
47
|
+
function baseConfigs() {
|
|
48
|
+
return [
|
|
49
|
+
...commentsConfig(),
|
|
50
|
+
...nodeConfig(),
|
|
51
|
+
...jsoncConfig(),
|
|
52
|
+
...testConfig(),
|
|
53
|
+
...sonarjsConfig(),
|
|
54
|
+
...promiseConfig(),
|
|
55
|
+
...unicornConfig(),
|
|
56
|
+
...e18eConfig(),
|
|
57
|
+
...regexpConfig(),
|
|
58
|
+
]
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Global and test-file overrides. Flat config is last-match-wins, so these must be
|
|
62
|
+
// appended after typescriptConfig() (and, on the base entry point, javascriptConfig()
|
|
63
|
+
// and jsdocConfig()) on both entry points, not folded into baseConfigs(): otherwise a
|
|
64
|
+
// rule these set (e.g. @typescript-eslint/no-explicit-any: 'off' for test files) gets
|
|
65
|
+
// re-enabled by a later config with the same rule key for the same files.
|
|
66
|
+
function overrideConfigs() {
|
|
67
|
+
return [
|
|
68
|
+
{
|
|
69
|
+
rules: GLOBAL_RULES,
|
|
70
|
+
ignores: [IGNORE_PATTERNS[0]],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
files: GLOB_TESTS,
|
|
74
|
+
rules: TEST_RULES,
|
|
75
|
+
},
|
|
76
|
+
{ ignores: [IGNORE_PATTERNS[1]] },
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Builds the SCAYLE Storefront ESLint flat config for a framework-agnostic or
|
|
82
|
+
* plain TypeScript project. Nuxt projects should use
|
|
83
|
+
* `@scayle/eslint-config-storefront/nuxt` instead, since `@nuxt/eslint` already
|
|
84
|
+
* covers JavaScript, TypeScript, JSDoc, and import rules.
|
|
85
|
+
*
|
|
86
|
+
* @param {EslintConfigStorefrontOptions} [config]
|
|
87
|
+
* @returns {FlatConfigComposer<import('eslint').Linter.Config, never>} Returns a FlatConfigComposer object to be consumed in projects eslint.config.mjs files
|
|
88
|
+
*/
|
|
89
|
+
export const storefront = function (config = {}) {
|
|
90
|
+
/** @type {FlatConfigComposer<import('eslint').Linter.Config, never>} */
|
|
91
|
+
const flatConfigComposer = new FlatConfigComposer()
|
|
92
|
+
|
|
93
|
+
const configs = [
|
|
94
|
+
...baseConfigs(),
|
|
95
|
+
gitignore({ strict: false }),
|
|
96
|
+
...ignoresConfig(),
|
|
97
|
+
...importXConfig(),
|
|
98
|
+
...javascriptConfig(),
|
|
99
|
+
...typescriptConfig(config.typescript),
|
|
100
|
+
...jsdocConfig(),
|
|
101
|
+
// Set tsconfigRootDir for all TypeScript files to support monorepo structure
|
|
102
|
+
// This ensures ESLint uses the correct tsconfig.json when multiple exist
|
|
103
|
+
{
|
|
104
|
+
files: ['**/*.mjs', '**/*.cjs', '**/*.ts', '**/*.tsx'],
|
|
105
|
+
languageOptions: {
|
|
106
|
+
parserOptions: {
|
|
107
|
+
tsconfigRootDir: process.cwd(),
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
...overrideConfigs(),
|
|
112
|
+
]
|
|
113
|
+
|
|
114
|
+
return flatConfigComposer.append(...configs)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Builds the SCAYLE Storefront ESLint flat config for a Nuxt project. Omits
|
|
119
|
+
* JavaScript, TypeScript, JSDoc, ignores, and import rules, since `@nuxt/eslint`
|
|
120
|
+
* already provides those for a Nuxt project.
|
|
121
|
+
*
|
|
122
|
+
* @returns {FlatConfigComposer<import('eslint').Linter.Config, never>} Returns a FlatConfigComposer object to be consumed in projects eslint.config.mjs files
|
|
123
|
+
*/
|
|
124
|
+
export const storefrontNuxt = function () {
|
|
125
|
+
/** @type {FlatConfigComposer<import('eslint').Linter.Config, never>} */
|
|
126
|
+
const flatConfigComposer = new FlatConfigComposer()
|
|
127
|
+
|
|
128
|
+
return flatConfigComposer.append(...baseConfigs(), ...overrideConfigs())
|
|
129
|
+
}
|