Skip to content

Commit

Permalink
feat(package.json, typegen.ts): add Next.js ESLint plugin and config …
Browse files Browse the repository at this point in the history
…integration

feat(configs): introduce Next.js and React specific ESLint rules
refactor(typescript/config.ts): add no-misused-promises rule to address React Hook Form discussion
chore(utils/extension.ts): import Next.js ESLint plugin with ts-expect-error for missing types

feat(utils/factory.ts): add react and nextjs config imports and conditionally apply them based on package existence to support linting for React and Next.js projects
  • Loading branch information
Bluzzi committed Oct 1, 2024
1 parent b34bdb9 commit 80fd52b
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
},
"dependencies": {
"@eslint/js": "^9.1.1",
"@next/eslint-plugin-next": "^14.2.3",
"@stylistic/eslint-plugin": "^1.7.2",
"@typescript-eslint/eslint-plugin": "^7.7.1",
"@typescript-eslint/parser": "^7.7.1",
Expand Down
23 changes: 23 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions scripts/typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { javascript } from "#/configs/javascript";
import { typescript } from "#/configs/typescript";
import { stylistic } from "#/configs/stylistic";
import { node } from "#/configs/node";
import { react } from "#/configs/react";
import { nextjs } from "#/configs/nextjs";

/**
* Combine array and non-array configs into a single array.
Expand All @@ -23,6 +25,8 @@ const configs = await combine(
node(),
stylistic(),
typescript(),
react(),
nextjs(),
);

const configNames = configs.map(i => i.name).filter(Boolean) as string[];
Expand Down
22 changes: 22 additions & 0 deletions src/configs/nextjs/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* eslint-disable ts/no-unsafe-member-access */
/* eslint-disable ts/no-unsafe-assignment */

import type { TypedFlatConfigItem } from "#/types/type";
import { nextjsPlugin } from "#/utils/extension";
import { configName } from "#/utils/naming";

export const nextjs = (): TypedFlatConfigItem[] => {
return [
{
name: configName("nextjs", "rules"),
files: ["**/*.ts", "**/*.tsx"],
plugins: {
node: nextjsPlugin,
},
rules: {
...nextjsPlugin.configs.recommended.rules,
...nextjsPlugin.configs["core-web-vitals"].rules,
},
},
];
};
1 change: 1 addition & 0 deletions src/configs/nextjs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./config";
22 changes: 22 additions & 0 deletions src/configs/react/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* eslint-disable ts/no-unsafe-assignment */

import type { TypedFlatConfigItem } from "#/types/type";
import { nextjsPlugin } from "#/utils/extension";
import { configName } from "#/utils/naming";

// TODO: https://github.com/antfu/eslint-config/blob/main/src/configs/react.ts
// TODO: https://github.com/we-use/eslint-config/issues/13

export const react = (): TypedFlatConfigItem[] => {
return [
{
name: configName("nextjs", "rules"),
files: ["**/*.ts", "**/*.tsx"],
plugins: {
node: nextjsPlugin,
},
rules: {
},
},
];
};
1 change: 1 addition & 0 deletions src/configs/react/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./config";
1 change: 1 addition & 0 deletions src/configs/typescript/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export const typescript = ({ tsconfigPath }: ParamsTS = {}): TypedFlatConfigItem
"no-return-await": "off",
"ts/return-await": "error",
"ts/strict-boolean-expressions": "error",
"ts/no-misused-promises": ["error", { checksVoidReturn: { attributes: false } }], // https://github.com/orgs/react-hook-form/discussions/8622
},
},
];
Expand Down
2 changes: 2 additions & 0 deletions src/utils/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@ export { default as antfuPlugin } from "eslint-plugin-antfu";
export { default as nodePlugin } from "eslint-plugin-n";
export { default as stylisticPlugin } from "@stylistic/eslint-plugin";
export { default as typescriptPlugin } from "@typescript-eslint/eslint-plugin";
// @ts-expect-error no types declarations
export { default as nextjsPlugin } from "@next/eslint-plugin-next";

export { default as typescriptParser } from "@typescript-eslint/parser";
16 changes: 16 additions & 0 deletions src/utils/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import { stylistic } from "#/configs/stylistic/config";
import { node } from "#/configs/node";
import { logger } from "#/utils/logger";
import { ignore } from "#/configs/ignore";
import { nextjs } from "#/configs/nextjs";
import { react } from "#/configs/react";

export const eslintConfig = async (
options: OptionsConfig = {},
Expand All @@ -17,6 +19,8 @@ export const eslintConfig = async (

const enabled = {
typescript: isPackageExists("typescript"),
react: isPackageExists("react"),
nextjs: isPackageExists("next"),
};

// Ignore:
Expand All @@ -41,6 +45,18 @@ export const eslintConfig = async (
logger.info("stylistic - config enabled");
configs.push(stylistic(options.stylistic));

// React:
if (enabled.react) {
logger.info("react - config enabled");
configs.push(react());
}

// NextJS:
if (enabled.nextjs) {
logger.info("nextjs - config enabled");
configs.push(nextjs());
}

// Compose:
const composer = new FlatConfigComposer<TypedFlatConfigItem, ConfigNames>();

Expand Down

0 comments on commit 80fd52b

Please sign in to comment.