Skip to content

Commit 3e2984a

Browse files
committed
feat: eslint web config
1 parent a3eafae commit 3e2984a

File tree

2 files changed

+267
-0
lines changed

2 files changed

+267
-0
lines changed

packages/eslint-config-web/index.mjs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// eslint-disable-next-line import/no-named-as-default
2+
import antfu from '@antfu/eslint-config'
3+
import checkFile from 'eslint-plugin-check-file'
4+
5+
/**
6+
* Create a customizable ESLint configuration
7+
*
8+
* @typedef {import('@antfu/eslint-config').OptionsFormatters} FormatterOptions
9+
* @typedef {import('@antfu/eslint-config').TypedFlatConfigItem} FlatConfigItem
10+
*
11+
* @param {Object} options - Configuration options
12+
* @param {string[]} [options.ignores] - Additional files to ignore
13+
* @param {boolean|FormatterOptions} [options.formatters=true] - Custom formatters or boolean to enable default ones
14+
* @param {FlatConfigItem['rules']} [options.unicornOverrides={}] - Custom unicorn rule overrides
15+
* @param {FlatConfigItem['rules']} [options.stylisticOverrides={}] - Custom stylistic rule overrides
16+
* @param {FlatConfigItem[]} [userConfig] - User-provided ESLint configuration
17+
*/
18+
function createConfig(options = {}, ...userConfig) {
19+
const {
20+
ignores = [],
21+
formatters = true,
22+
unicornOverrides = {},
23+
stylisticOverrides = {},
24+
} = options
25+
26+
const defaultIgnores = [
27+
'**/*.{jpg,jpeg,webp,png,gif,svg,ico,avif}',
28+
]
29+
30+
const defaultUnicornOverrides = {
31+
'unicorn/filename-case': ['error', {
32+
case: 'kebabCase',
33+
ignore: [
34+
'pull_request_template.md',
35+
],
36+
}],
37+
}
38+
39+
const defaultStylisticOverrides = {
40+
'style/arrow-parens': ['error', 'always'],
41+
'style/brace-style': ['error', '1tbs'],
42+
}
43+
44+
return antfu({
45+
formatters,
46+
react: true,
47+
ignores: [...defaultIgnores, ...ignores],
48+
unicorn: {
49+
overrides: { ...defaultUnicornOverrides, ...unicornOverrides },
50+
},
51+
stylistic: {
52+
overrides: { ...defaultStylisticOverrides, ...stylisticOverrides },
53+
},
54+
rules: {
55+
'node/prefer-global/process': 'off',
56+
'perfectionist/sort-imports': ['error', {
57+
groups: [
58+
'side-effect',
59+
'builtin',
60+
'external',
61+
'internal',
62+
['parent', 'sibling', 'index'],
63+
['object', 'unknown'],
64+
],
65+
newlinesBetween: 'always',
66+
order: 'asc',
67+
type: 'natural',
68+
}],
69+
},
70+
}, {
71+
files: ['src/**/*.*'],
72+
plugins: {
73+
'check-file': checkFile,
74+
},
75+
rules: {
76+
'check-file/filename-blocklist': ['error', {
77+
'**/*.story.ts(x)': '*.stories.ts(x)',
78+
'**/*.spec.ts(x)': '*.test.ts(x)',
79+
}],
80+
'check-file/folder-naming-convention': [
81+
'error',
82+
{
83+
'src/!(app)/**': 'KEBAB_CASE',
84+
'src/app/**': 'NEXT_JS_APP_ROUTER_CASE',
85+
},
86+
],
87+
},
88+
}, ...userConfig)
89+
}
90+
91+
const config = createConfig()
92+
93+
export default config
94+
export { createConfig }

packages/eslint-config-web/readme.md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
# @strv/eslint-config-web
2+
3+
- [@strv/eslint-config-web](#strveslint-config-web)
4+
- [Installation](#installation)
5+
- [Rulesets](#rulesets)
6+
- [Usage](#usage)
7+
- [Customizations](#customizations)
8+
- [Formatters](#formatters)
9+
- [Unicorn \& Stylistic](#unicorn--stylistic)
10+
- [Other config](#other-config)
11+
- [VSCode](#vscode)
12+
- [License](#license)
13+
> Configuration for Web projects.
14+
15+
## Installation
16+
17+
```sh
18+
# npm
19+
npm install -D @strv/eslint-config-web
20+
# yarn
21+
yard add -D @strv/eslint-config-web
22+
# pnpm
23+
pnpm add -D @strv/eslint-config-web
24+
```
25+
26+
## Rulesets
27+
28+
- `'@strv/eslint-config-web'`: STRV Frontend Ruleset that focuses on code correctness for web projects, which use TypeScript and React.
29+
30+
This ruleset is based on [Antfu ESLint Ruleset](https://github.com/antfu/eslint-config). If you are interested in more details about the rules, you can check the ruleset in [Config Inspector](https://eslint-config.antfu.me/).
31+
32+
## Usage
33+
34+
```js
35+
import config from "@strv/eslint-config-web";
36+
37+
export default config;
38+
```
39+
40+
### Customizations
41+
42+
```js
43+
import { createConfig } from "@strv/eslint-config-web";
44+
45+
const config = createConfig(
46+
{
47+
ignores: ["devops/*", "custom-scripts/*"],
48+
unicornOverrides: {
49+
"unicorn/filename-case": [
50+
"error",
51+
{
52+
case: "camelCase",
53+
ignore: ["pull_request_template.md"],
54+
},
55+
],
56+
},
57+
stylisticOverrides: {
58+
"style/arrow-parens": ["error", "always"],
59+
},
60+
},
61+
{
62+
files: ["**/*"],
63+
rules: {
64+
"check-file/filename-blocklist": "off",
65+
},
66+
},
67+
);
68+
69+
export default config;
70+
```
71+
72+
#### Formatters
73+
74+
If you would like to see more details about the exposed option `formatters`, please check the [official documentation](https://github.com/antfu/eslint-config?tab=readme-ov-file#formatters).
75+
76+
#### Unicorn & Stylistic
77+
78+
`unicornOverrides` and `stylisticOverrides` provide an option to adjust specific plugin rules.
79+
80+
`unicorn/*` rules should be listed in `unicornOverrides`, and `style/*` rules should be listed in `stylisticOverrides`.
81+
82+
#### Other config
83+
84+
If needed, you can pass additional flat config objects as arguments with unlimited config options.
85+
86+
```js
87+
import { createConfig } from "@strv/eslint-config-web";
88+
89+
const config = createConfig(
90+
// Create Config Options
91+
{
92+
ignores: ["devops/*"],
93+
},
94+
// Flat Config object without restrictions
95+
{
96+
files: ["**/*"],
97+
rules: {
98+
"antfu/top-level-function": "off",
99+
"check-file/filename-blocklist": "off",
100+
},
101+
},
102+
{
103+
files: ["cypress/*"],
104+
plugins: {
105+
// integrate cypress plugin
106+
}
107+
rules: {
108+
// cypress specific rules
109+
},
110+
},
111+
);
112+
113+
export default config;
114+
```
115+
116+
### VSCode
117+
118+
Update the `.vscode/settings.json` on you project to include this setup:
119+
120+
```json
121+
// Disable the default formatter, use eslint instead
122+
"prettier.enable": false,
123+
"editor.formatOnSave": false,
124+
125+
// Auto fix
126+
"editor.codeActionsOnSave": {
127+
"source.fixAll.eslint": "explicit",
128+
"source.organizeImports": "never"
129+
},
130+
131+
// Silent the stylistic rules in you IDE, but still auto fix them
132+
"eslint.rules.customizations": [
133+
{ "rule": "style/*", "severity": "off", "fixable": true },
134+
{ "rule": "format/*", "severity": "off", "fixable": true },
135+
{ "rule": "*-indent", "severity": "off", "fixable": true },
136+
{ "rule": "*-spacing", "severity": "off", "fixable": true },
137+
{ "rule": "*-spaces", "severity": "off", "fixable": true },
138+
{ "rule": "*-order", "severity": "off", "fixable": true },
139+
{ "rule": "*-dangle", "severity": "off", "fixable": true },
140+
{ "rule": "*-newline", "severity": "off", "fixable": true },
141+
{ "rule": "*quotes", "severity": "off", "fixable": true },
142+
{ "rule": "*semi", "severity": "off", "fixable": true }
143+
],
144+
145+
// Enable eslint for all supported languages
146+
"eslint.validate": [
147+
"javascript",
148+
"javascriptreact",
149+
"typescript",
150+
"typescriptreact",
151+
"vue",
152+
"html",
153+
"markdown",
154+
"json",
155+
"jsonc",
156+
"yaml",
157+
"toml",
158+
"xml",
159+
"gql",
160+
"graphql",
161+
"astro",
162+
"svelte",
163+
"css",
164+
"less",
165+
"scss",
166+
"pcss",
167+
"postcss"
168+
],
169+
```
170+
171+
## License
172+
173+
See the [LICENSE](LICENSE) file for information.

0 commit comments

Comments
 (0)