@jimmy.codes/eslint-config
Version:
A simple, modern ESLint config that covers most use cases.
94 lines (91 loc) • 3.49 kB
JavaScript
import { GLOB_JSX, GLOB_TSX } from "./globs-CRO5v7xy.js";
import { hasNext, hasTypescript, hasVite } from "./has-dependency-7vimNBSE.js";
import { interopDefault } from "./interop-default-D4l3hsYQ.js";
import { upwarn } from "./upwarn-C7t3ub-R.js";
import globals from "globals";
//#region src/rules/react.ts
const nextAllowedExportNames = [
"dynamic",
"dynamicParams",
"revalidate",
"fetchCache",
"runtime",
"preferredRegion",
"maxDuration",
"config",
"generateStaticParams",
"metadata",
"generateMetadata",
"viewport",
"generateViewport"
];
const reactRules = async () => {
const [{ configs: reactConfigs }, jsxA11yPlugin] = await Promise.all([interopDefault(import("@eslint-react/eslint-plugin")), interopDefault(import("eslint-plugin-jsx-a11y"))]);
const isUsingNextjs = hasNext();
const isUsingVite = hasVite();
const reactPluginRules = hasTypescript() ? reactConfigs["recommended-type-checked"].rules : reactConfigs.recommended.rules;
return {
...jsxA11yPlugin.flatConfigs.recommended.rules,
...upwarn(reactPluginRules),
"@eslint-react/dom/no-string-style-prop": "error",
"@eslint-react/hooks-extra/no-direct-set-state-in-use-effect": "error",
"@eslint-react/jsx-key-before-spread": "error",
"@eslint-react/jsx-shorthand-boolean": "error",
"@eslint-react/jsx-shorthand-fragment": "error",
"@eslint-react/naming-convention/component-name": "error",
"@eslint-react/naming-convention/use-state": "error",
"@eslint-react/no-children-prop": "error",
"@eslint-react/no-class-component": "error",
"@eslint-react/no-missing-context-display-name": "error",
"@eslint-react/no-unnecessary-key": "error",
"@eslint-react/no-unnecessary-use-callback": "error",
"@eslint-react/no-unnecessary-use-memo": "error",
"@eslint-react/no-useless-fragment": "error",
"@eslint-react/prefer-namespace-import": "error",
"react-compiler/react-compiler": "error",
"react-hooks/exhaustive-deps": "error",
"react-hooks/rules-of-hooks": "error",
"react-refresh/only-export-components": ["warn", {
allowConstantExport: isUsingVite,
allowExportNames: isUsingNextjs ? nextAllowedExportNames : []
}]
};
};
//#endregion
//#region src/configs/react.ts
async function reactConfig() {
const [reactPlugin, jsxA11yPlugin, reactHooksPlugin, reactRefreshPlugin, reactCompilerPlugin] = await Promise.all([
interopDefault(import("@eslint-react/eslint-plugin")),
interopDefault(import("eslint-plugin-jsx-a11y")),
import("eslint-plugin-react-hooks"),
interopDefault(import("eslint-plugin-react-refresh")),
import("eslint-plugin-react-compiler")
]);
const reactPlugins = reactPlugin.configs.all.plugins;
return [{
files: [GLOB_JSX, GLOB_TSX],
languageOptions: {
globals: { ...globals.browser },
parserOptions: {
ecmaFeatures: { jsx: true },
jsxPragma: null
}
},
name: "jimmy.codes/react",
plugins: {
"@eslint-react": reactPlugins["@eslint-react"],
"@eslint-react/dom": reactPlugins["@eslint-react/dom"],
"@eslint-react/hooks-extra": reactPlugins["@eslint-react/hooks-extra"],
"@eslint-react/naming-convention": reactPlugins["@eslint-react/naming-convention"],
"@eslint-react/web-api": reactPlugins["@eslint-react/web-api"],
"jsx-a11y": jsxA11yPlugin,
"react-compiler": reactCompilerPlugin,
"react-hooks": reactHooksPlugin,
"react-refresh": reactRefreshPlugin
},
rules: await reactRules(),
settings: { react: { version: "detect" } }
}];
}
//#endregion
export { reactConfig as default };