Skip to content

Commit a3e230e

Browse files
authored
[add] stylistic plugin (#50)
1 parent a6a1d8e commit a3e230e

File tree

10 files changed

+1243
-973
lines changed

10 files changed

+1243
-973
lines changed

components/BlockEditor.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ async function uploadByFile(file: File) {
1515
return { success: 1, file: { url } };
1616
} catch (error) {
1717
console.error(error);
18+
1819
return { success: 0 };
1920
}
2021
}

eslint.config.mjs

Lines changed: 72 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
// @ts-check
2-
import { FlatCompat } from '@eslint/eslintrc';
1+
import cspellPlugin from '@cspell/eslint-plugin';
32
import eslint from '@eslint/js';
3+
// @ts-expect-error eslint-plugin-next doesn't come with TypeScript definitions
4+
import nextPlugin from '@next/eslint-plugin-next';
5+
import stylistic from '@stylistic/eslint-plugin';
46
import eslintConfigPrettier from 'eslint-config-prettier';
57
import react from 'eslint-plugin-react';
68
import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort';
@@ -10,18 +12,21 @@ import { fileURLToPath } from 'url';
1012

1113
/**
1214
* @see{@link https://github.com/typescript-eslint/typescript-eslint/blob/main/eslint.config.mjs}
15+
* @see{@link https://github.com/vercel/next.js/issues/71763#issuecomment-2476838298}
1316
*/
1417

15-
const tsconfigRootDir = fileURLToPath(new URL('.', import.meta.url)),
16-
flatCompat = new FlatCompat();
18+
const tsconfigRootDir = fileURLToPath(new URL('.', import.meta.url));
1719

1820
export default tsEslint.config(
1921
// register all of the plugins up-front
2022
{
2123
plugins: {
2224
'@typescript-eslint': tsEslint.plugin,
25+
'@next/next': nextPlugin,
2326
react,
27+
'@stylistic': stylistic,
2428
'simple-import-sort': simpleImportSortPlugin,
29+
'@cspell': cspellPlugin,
2530
},
2631
},
2732
{
@@ -32,7 +37,6 @@ export default tsEslint.config(
3237
// extends ...
3338
eslint.configs.recommended,
3439
...tsEslint.configs.recommended,
35-
...flatCompat.extends('plugin:@next/next/core-web-vitals'),
3640

3741
// base config
3842
{
@@ -45,13 +49,30 @@ export default tsEslint.config(
4549
},
4650
},
4751
rules: {
52+
...nextPlugin.configs.recommended.rules,
53+
...nextPlugin.configs['core-web-vitals'].rules,
54+
'arrow-body-style': ['error', 'as-needed'],
4855
'no-empty-pattern': 'warn',
49-
'simple-import-sort/exports': 'error',
50-
'simple-import-sort/imports': 'error',
51-
'@typescript-eslint/no-unused-vars': 'warn',
52-
'@typescript-eslint/no-explicit-any': 'warn',
53-
'@typescript-eslint/no-empty-object-type': 'off',
54-
'@typescript-eslint/no-unsafe-declaration-merging': 'warn',
56+
'no-console': ['error', { allow: ['warn', 'error', 'info'] }],
57+
'no-restricted-syntax': [
58+
'error',
59+
{
60+
selector: "TSPropertySignature[key.name='children']",
61+
message:
62+
'Please use PropsWithChildren<T> instead of defining children manually',
63+
},
64+
],
65+
'consistent-return': 'warn',
66+
'prefer-destructuring': ['error', { object: true, array: true }],
67+
// next
68+
'@next/next/no-sync-scripts': 'warn',
69+
// react
70+
'react/no-unescaped-entities': 'off',
71+
'react/self-closing-comp': ['error', { component: true, html: true }],
72+
'react/jsx-curly-brace-presence': [
73+
'error',
74+
{ props: 'never', children: 'never' },
75+
],
5576
'react/jsx-no-target-blank': 'warn',
5677
'react/jsx-sort-props': [
5778
'error',
@@ -61,18 +82,47 @@ export default tsEslint.config(
6182
noSortAlphabetically: true,
6283
},
6384
],
64-
'@next/next/no-sync-scripts': 'warn',
65-
},
66-
},
67-
{
68-
files: ['**/*.js'],
69-
extends: [tsEslint.configs.disableTypeChecked],
70-
rules: {
71-
// turn off other type-aware rules
72-
'@typescript-eslint/internal/no-poorly-typed-ts-props': 'off',
85+
// typescript
86+
'@typescript-eslint/no-unused-vars': 'warn',
87+
'@typescript-eslint/no-explicit-any': 'warn',
88+
'@typescript-eslint/no-empty-object-type': 'off',
89+
'@typescript-eslint/no-unsafe-declaration-merging': 'warn',
90+
'@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
91+
92+
// stylistic
93+
'@stylistic/padding-line-between-statements': [
94+
'error',
95+
{ blankLine: 'always', prev: '*', next: 'return' },
96+
{ blankLine: 'always', prev: 'directive', next: '*' },
97+
{ blankLine: 'any', prev: 'directive', next: 'directive' },
98+
{
99+
blankLine: 'always',
100+
prev: '*',
101+
next: ['enum', 'interface', 'type'],
102+
},
103+
],
73104

74-
// turn off rules that don't apply to JS code
75-
'@typescript-eslint/explicit-function-return-type': 'off',
105+
// simple-import-sort
106+
'simple-import-sort/exports': 'error',
107+
'simple-import-sort/imports': 'error',
108+
// spellchecker
109+
'@cspell/spellchecker': [
110+
'warn',
111+
{
112+
cspell: {
113+
language: 'en',
114+
dictionaries: [
115+
'typescript',
116+
'node',
117+
'html',
118+
'css',
119+
'bash',
120+
'npm',
121+
'pnpm',
122+
],
123+
},
124+
},
125+
],
76126
},
77127
},
78128
eslintConfigPrettier,

package.json

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@idea2app/next-bootstrap-ts",
3-
"version": "1.7.1",
3+
"version": "1.7.2",
44
"description": "React project scaffold based on TypeScript, Next.js, Bootstrap & Workbox.",
55
"private": true,
66
"engines": {
@@ -12,15 +12,15 @@
1212
"@editorjs/header": "^2.8.8",
1313
"@editorjs/image": "^2.10.2",
1414
"@editorjs/link": "^2.6.2",
15-
"@editorjs/list": "^2.0.4",
15+
"@editorjs/list": "^2.0.6",
1616
"@editorjs/paragraph": "^2.11.7",
1717
"@editorjs/quote": "~2.7.6",
1818
"@mdx-js/loader": "^3.1.0",
1919
"@mdx-js/react": "^3.1.0",
20-
"@next/mdx": "^15.1.7",
21-
"@sentry/nextjs": "^9.1.0",
20+
"@next/mdx": "^15.2.1",
21+
"@sentry/nextjs": "^9.4.0",
2222
"copy-webpack-plugin": "^12.0.2",
23-
"core-js": "^3.40.0",
23+
"core-js": "^3.41.0",
2424
"editorjs-html": "^4.0.5",
2525
"idea-react": "^2.0.0-rc.8",
2626
"koajax": "^3.1.1",
@@ -33,7 +33,7 @@
3333
"mobx-react": "^9.2.0",
3434
"mobx-restful": "^2.1.0",
3535
"mobx-restful-table": "^2.0.1",
36-
"next": "^15.1.7",
36+
"next": "^15.2.1",
3737
"next-pwa": "~5.6.0",
3838
"next-ssr-middleware": "^0.8.9",
3939
"next-with-less": "^3.0.1",
@@ -46,36 +46,37 @@
4646
"remark-frontmatter": "^5.0.0",
4747
"remark-gfm": "^4.0.1",
4848
"remark-mdx-frontmatter": "^5.0.0",
49-
"undici": "^7.3.0",
49+
"undici": "^7.4.0",
5050
"web-utility": "^4.4.3",
5151
"webpack": "^5.98.0"
5252
},
5353
"devDependencies": {
5454
"@babel/plugin-proposal-decorators": "^7.25.9",
5555
"@babel/plugin-transform-typescript": "^7.26.8",
5656
"@babel/preset-react": "^7.26.3",
57+
"@cspell/eslint-plugin": "^8.17.5",
5758
"@eslint/compat": "^1.2.7",
5859
"@eslint/eslintrc": "^3.3.0",
5960
"@eslint/js": "^9.21.0",
61+
"@next/eslint-plugin-next": "^15.2.1",
62+
"@stylistic/eslint-plugin": "^4.2.0",
6063
"@softonus/prettier-plugin-duplicate-remover": "^1.1.2",
6164
"@types/eslint-config-prettier": "^6.11.3",
62-
"@types/eslint__eslintrc": "^2.1.2",
63-
"@types/lodash": "^4.17.15",
65+
"@types/lodash": "^4.17.16",
6466
"@types/next-pwa": "^5.6.9",
6567
"@types/node": "^22.13.5",
6668
"@types/react": "^18.3.18",
6769
"eslint": "^9.21.0",
68-
"eslint-config-next": "^15.1.7",
69-
"eslint-config-prettier": "^10.0.1",
70+
"eslint-config-prettier": "^10.0.2",
7071
"eslint-plugin-react": "^7.37.4",
7172
"eslint-plugin-simple-import-sort": "^12.1.1",
7273
"globals": "^16.0.0",
7374
"husky": "^9.1.7",
7475
"lint-staged": "^15.4.3",
75-
"prettier": "^3.5.2",
76+
"prettier": "^3.5.3",
7677
"prettier-plugin-css-order": "^2.1.2",
77-
"typescript": "~5.7.3",
78-
"typescript-eslint": "^8.24.1"
78+
"typescript": "~5.8.2",
79+
"typescript-eslint": "^8.26.0"
7980
},
8081
"resolutions": {
8182
"next": "$next"

pages/_document.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export default function Document() {
77
<link rel="icon" href="/favicon.ico" />
88

99
<link rel="manifest" href="/manifest.json" />
10-
<script src="https://polyfill.web-cell.dev/feature/PWAManifest.js"></script>
10+
<script src="https://polyfill.web-cell.dev/feature/PWAManifest.js" />
1111

1212
<link
1313
rel="stylesheet"

pages/api/core.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export function safeAPI(handler: NextAPI): NextAPI {
2020
console.error(error);
2121

2222
res.status(400);
23+
2324
return res.send({ message: (error as Error).message });
2425
}
2526
const { message, response } = error;

pages/api/hello.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import type { NextApiResponse } from 'next';
33

44
import { safeAPI } from './core';
55

6-
type Data = {
6+
interface Data {
77
name: string;
8-
};
8+
}
99

1010
export default safeAPI(async (req, res: NextApiResponse<Data>) =>
1111
res.status(401).json({ name: 'John Doe' }),

pages/component.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const ComponentPage = observer(() => {
5858
<h1 className="my-4 text-center">{title}</h1>
5959

6060
<Example title="HTML Editor">
61-
<HTMLEditor defaultValue="Hello, HTML!" onChange={console.log} />
61+
<HTMLEditor defaultValue="Hello, HTML!" onChange={console.info} />
6262
</Example>
6363

6464
<Example title="Block Editor">

pages/pagination.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export default class PaginationPage extends Component {
6767
columns={this.columns}
6868
store={repositoryStore}
6969
translator={i18n}
70-
onCheck={console.log}
70+
onCheck={console.info}
7171
/>
7272
</Container>
7373
);

0 commit comments

Comments
 (0)