Skip to content

Commit

Permalink
fix: use @eslint/compat to fix eslint v9 + react plugin (#113)
Browse files Browse the repository at this point in the history
* fix: use eslint v9 when choosing react

fixes #106

* fix: use `--force`

* chore: add a note

* fix: ask installing eslint v8/v9

* chore: add more tests

* fix: rm an unused assignment
  • Loading branch information
aladdin-add authored May 13, 2024
1 parent 12886ee commit 61a385e
Show file tree
Hide file tree
Showing 45 changed files with 232 additions and 150 deletions.
54 changes: 42 additions & 12 deletions lib/config-generator.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ export class ConfigGenerator {
this.packageJsonPath = options.packageJsonPath || findPackageJson(this.cwd);
this.answers = options.answers || {};
this.result = {
devDependencies: [],
devDependencies: ["eslint@9.x"],
configFilename: "eslint.config.js",
configContent: ""
configContent: "",
installFlags: ["-D"]
};
}

Expand Down Expand Up @@ -72,6 +73,19 @@ export class ConfigGenerator {
{ message: "None of these", name: "none" }
]
},
{
type: "select",
name: "eslintVersion",
message: "The React plugin doesn't officially support ESLint v9 yet. What would you like to do?",
initial: 0,
choices: [
{ message: "Install ESLint v9.x with compatibility utilities", name: "9.x" },
{ message: "Install ESLint v8.x", name: "8.x" }
],
skip() {
return this.state.answers.framework !== "react";
}
},
{
type: "select",
name: "language",
Expand Down Expand Up @@ -166,9 +180,18 @@ const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: plug
}

if (this.answers.framework === "react") {
this.result.devDependencies.push("eslint-plugin-react");
importContent += "import pluginReactConfig from \"eslint-plugin-react/configs/recommended.js\";\n";
exportContent += " pluginReactConfig,\n";
if (this.answers.eslintVersion === "9.x") {
this.result.devDependencies.push("eslint-plugin-react", "@eslint/compat");
this.result.installFlags.push("--force");
importContent += "import pluginReactConfig from \"eslint-plugin-react/configs/recommended.js\";\n";
importContent += "import { fixupConfigRules } from \"@eslint/compat\";\n";
exportContent += " ...fixupConfigRules(pluginReactConfig),\n";
} else if (this.answers.eslintVersion === "8.x") {
this.result.devDependencies[0] = "eslint@8.x";
this.result.devDependencies.push("eslint-plugin-react");
importContent += "import pluginReactConfig from \"eslint-plugin-react/configs/recommended.js\";\n";
exportContent += " pluginReactConfig,\n";
}
}
if (this.answers.config) {
const config = this.answers.config;
Expand All @@ -179,7 +202,19 @@ const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: plug
const peers = fetchPeerDependencies(config.packageName);

if (peers !== null) {
this.result.devDependencies.push(...peers);
const eslintIndex = peers.findIndex(dep => (dep.startsWith("eslint@")));

if (eslintIndex === -1) {
// eslint is not in the peer dependencies

this.result.devDependencies.push(...peers);
} else {

// eslint is in the peer dependencies => overwrite eslint version
this.result.devDependencies[0] = peers[eslintIndex];
peers.splice(eslintIndex, 1);
this.result.devDependencies.push(...peers);
}
}

if (config.type === "flat" || config.type === void 0) {
Expand All @@ -198,11 +233,6 @@ const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: plug
this.result.devDependencies.push("@eslint/eslintrc", "@eslint/js");
}

const hasEslint = this.result.devDependencies.some(dep => (/^eslint(@|$)/u.test(dep)));

if (!hasEslint) {
this.result.devDependencies.push("eslint");
}
this.result.configContent = `${importContent}
${needCompatHelper ? helperContent : ""}
export default [\n${exportContent}];`;
Expand Down Expand Up @@ -238,7 +268,7 @@ export default [\n${exportContent}];`;
})).packageManager;

log.info("☕️Installing...");
installSyncSaveDev(this.result.devDependencies, packageManager);
installSyncSaveDev(this.result.devDependencies, packageManager, this.result.installFlags);
await writeFile(configPath, this.result.configContent);

// import("eslint") won't work in some cases.
Expand Down
5 changes: 3 additions & 2 deletions lib/utils/npm-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,13 @@ function findPackageJson(startDir) {
* Install node modules synchronously and save to devDependencies in package.json
* @param {string|string[]} packages Node module or modules to install
* @param {string} packageManager Package manager to use for installation.
* @param {string[]} installFlags Flags to pass to the package manager.
* @returns {void}
*/
function installSyncSaveDev(packages, packageManager = "npm") {
function installSyncSaveDev(packages, packageManager = "npm", installFlags = ["-D"]) {
const packageList = Array.isArray(packages) ? packages : [packages];
const installCmd = packageManager === "yarn" ? "add" : "install";
const installProcess = spawn.sync(packageManager, [installCmd, "-D"].concat(packageList), { stdio: "inherit" });
const installProcess = spawn.sync(packageManager, [installCmd, ...installFlags].concat(packageList), { stdio: "inherit" });
const error = installProcess.error;

if (error && error.code === "ENOENT") {
Expand Down
5 changes: 4 additions & 1 deletion tests/__snapshots__/config@eslint-config-airbnb
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@ export default [
];",
"configFilename": "eslint.config.mjs",
"devDependencies": [
"eslint-config-airbnb",
"eslint@^7.32.0 || ^8.2.0",
"eslint-config-airbnb",
"eslint-plugin-import@^2.25.3",
"eslint-plugin-jsx-a11y@^6.5.1",
"eslint-plugin-react@^7.28.0",
"eslint-plugin-react-hooks@^4.3.0",
"@eslint/eslintrc",
"@eslint/js",
],
"installFlags": [
"-D",
],
}
5 changes: 4 additions & 1 deletion tests/__snapshots__/config@eslint-config-airbnb-base
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ export default [
];",
"configFilename": "eslint.config.mjs",
"devDependencies": [
"eslint-config-airbnb-base",
"eslint@^7.32.0 || ^8.2.0",
"eslint-config-airbnb-base",
"eslint-plugin-import@^2.25.2",
"@eslint/eslintrc",
"@eslint/js",
],
"installFlags": [
"-D",
],
}
5 changes: 4 additions & 1 deletion tests/__snapshots__/config@eslint-config-standard
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@ export default [
];",
"configFilename": "eslint.config.mjs",
"devDependencies": [
"eslint-config-standard",
"eslint@^8.0.1",
"eslint-config-standard",
"eslint-plugin-import@^2.25.2",
"eslint-plugin-n@^15.0.0 || ^16.0.0 ",
"eslint-plugin-promise@^6.0.0",
"@eslint/eslintrc",
"@eslint/js",
],
"installFlags": [
"-D",
],
}
5 changes: 4 additions & 1 deletion tests/__snapshots__/config@eslint-config-standard-flat
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ export default [
];",
"configFilename": "eslint.config.mjs",
"devDependencies": [
"eslint-config-standard",
"eslint@^8.0.1",
"eslint-config-standard",
"eslint-plugin-import@^2.25.2",
"eslint-plugin-n@^15.0.0 || ^16.0.0 ",
"eslint-plugin-promise@^6.0.0",
],
"installFlags": [
"-D",
],
}
5 changes: 4 additions & 1 deletion tests/__snapshots__/config@eslint-config-standard-flat2
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ export default [
];",
"configFilename": "eslint.config.mjs",
"devDependencies": [
"eslint-config-standard",
"eslint@^8.0.1",
"eslint-config-standard",
"eslint-plugin-import@^2.25.2",
"eslint-plugin-n@^15.0.0 || ^16.0.0 ",
"eslint-plugin-promise@^6.0.0",
],
"installFlags": [
"-D",
],
}
5 changes: 4 additions & 1 deletion tests/__snapshots__/config@eslint-config-xo
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ export default [
];",
"configFilename": "eslint.config.mjs",
"devDependencies": [
"eslint-config-xo",
"eslint@>=8.56.0",
"eslint-config-xo",
"@eslint/eslintrc",
"@eslint/js",
],
"installFlags": [
"-D",
],
}
5 changes: 4 additions & 1 deletion tests/__snapshots__/problems-commonjs-none-javascript
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@ export default [
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint@9.x",
"globals",
"@eslint/js",
"eslint",
],
"installFlags": [
"-D",
],
}
5 changes: 4 additions & 1 deletion tests/__snapshots__/problems-commonjs-none-typescript
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ export default [
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint@9.x",
"globals",
"@eslint/js",
"typescript-eslint",
"eslint",
],
"installFlags": [
"-D",
],
}
23 changes: 0 additions & 23 deletions tests/__snapshots__/problems-commonjs-react-typescript

This file was deleted.

5 changes: 4 additions & 1 deletion tests/__snapshots__/problems-commonjs-vue-javascript
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,12 @@ export default [
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint@9.x",
"globals",
"@eslint/js",
"eslint-plugin-vue",
"eslint",
],
"installFlags": [
"-D",
],
}
5 changes: 4 additions & 1 deletion tests/__snapshots__/problems-commonjs-vue-typescript
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,13 @@ export default [
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint@9.x",
"globals",
"@eslint/js",
"typescript-eslint",
"eslint-plugin-vue",
"eslint",
],
"installFlags": [
"-D",
],
}
5 changes: 4 additions & 1 deletion tests/__snapshots__/problems-esm-none-javascript
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,11 @@ export default [
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint@9.x",
"globals",
"@eslint/js",
"eslint",
],
"installFlags": [
"-D",
],
}
5 changes: 4 additions & 1 deletion tests/__snapshots__/problems-esm-none-typescript
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ export default [
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint@9.x",
"globals",
"@eslint/js",
"typescript-eslint",
"eslint",
],
"installFlags": [
"-D",
],
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ import pluginReactConfig from "eslint-plugin-react/configs/recommended.js";


export default [
{languageOptions: { globals: {...globals.browser, ...globals.node} }},
{languageOptions: { globals: globals.browser }},
pluginJs.configs.recommended,
pluginReactConfig,
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint@8.x",
"globals",
"@eslint/js",
"eslint-plugin-react",
"eslint",
],
"installFlags": [
"-D",
],
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ import pluginReactConfig from "eslint-plugin-react/configs/recommended.js";


export default [
{languageOptions: { globals: {...globals.browser, ...globals.node} }},
{languageOptions: { globals: globals.browser }},
pluginJs.configs.recommended,
...tseslint.configs.recommended,
pluginReactConfig,
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint@8.x",
"globals",
"@eslint/js",
"typescript-eslint",
"eslint-plugin-react",
"eslint",
],
"installFlags": [
"-D",
],
}
Loading

0 comments on commit 61a385e

Please sign in to comment.