Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use @eslint/compat to fix eslint v9 + react plugin #113

Merged
merged 6 commits into from
May 13, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 22 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.2.0"],
configFilename: "eslint.config.js",
configContent: ""
configContent: "",
installFlags: ["-D"]
};
}

Expand Down Expand Up @@ -67,7 +68,7 @@ export class ConfigGenerator {
message: "Which framework does your project use?",
initial: 0,
choices: [
{ message: "React", name: "react" },
{ message: "React (⚠️eslint v9 has not been officially supported.)", name: "react" },
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added a note, as it will output an warning when using npm install --force:

The config that you've selected requires the following dependencies:

eslint@^9.2.0, globals, @eslint/js, eslint-plugin-react, @eslint/compat
✔ Would you like to install them now? · No / Yes
✔ Which package manager do you want to use? · npm
☕️Installing...
npm WARN using --force Recommended protections disabled.
npm WARN idealTree Removing dependencies.eslint in favor of devDependencies.eslint
npm WARN idealTree Removing dependencies.globals in favor of devDependencies.globals
npm WARN idealTree Removing dependencies.@eslint/js in favor of devDependencies.@eslint/js
npm WARN idealTree Removing dependencies.eslint-plugin-react in favor of devDependencies.eslint-plugin-react
npm WARN ERESOLVE overriding peer dependency
npm WARN While resolving: example@1.0.0
npm WARN Found: eslint@8.57.0
npm WARN node_modules/eslint
npm WARN   peer eslint@"^6.0.0 || ^7.0.0 || >=8.0.0" from @eslint-community/eslint-utils@4.4.0
npm WARN   node_modules/@eslint-community/eslint-utils
npm WARN     @eslint-community/eslint-utils@"^4.2.0" from eslint@8.57.0
npm WARN   2 more (eslint-plugin-react, the root project)
npm WARN 
npm WARN Could not resolve dependency:
npm WARN peer eslint@"^3 || ^4 || ^5 || ^6 || ^7 || ^8" from eslint-plugin-react@7.34.1
npm WARN node_modules/eslint-plugin-react
npm WARN   dev eslint-plugin-react@"*" from the root project
npm WARN ERESOLVE overriding peer dependency
npm WARN While resolving: eslint-plugin-react@7.34.1
npm WARN Found: eslint@9.2.0
npm WARN node_modules/eslint
npm WARN   dev eslint@"^9.2.0" from the root project
npm WARN   1 more (@eslint-community/eslint-utils)
npm WARN 
npm WARN Could not resolve dependency:
npm WARN peer eslint@"^3 || ^4 || ^5 || ^6 || ^7 || ^8" from eslint-plugin-react@7.34.1
npm WARN node_modules/eslint-plugin-react
npm WARN   dev eslint-plugin-react@"*" from the root project
npm WARN 
npm WARN Conflicting peer dependency: eslint@8.57.0
npm WARN node_modules/eslint
npm WARN   peer eslint@"^3 || ^4 || ^5 || ^6 || ^7 || ^8" from eslint-plugin-react@7.34.1
npm WARN   node_modules/eslint-plugin-react
npm WARN     dev eslint-plugin-react@"*" from the root project

added 5 packages, removed 3 packages, and changed 19 packages in 30s

36 packages are looking for funding
  run `npm fund` for details

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will confuse people. What if we just kept this as "React", and then, if it is selected, output another message:

The React plugin doesn't officially support ESLint v9 yet. What would you like to do?

  • Install ESLint v9.x with compatibility utilities
  • Install ESLint v8.x

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 sounds good, will make a change later.

{ message: "Vue.js", name: "vue" },
{ message: "None of these", name: "none" }
]
Expand Down Expand Up @@ -166,9 +167,11 @@ const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: plug
}

if (this.answers.framework === "react") {
this.result.devDependencies.push("eslint-plugin-react");
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";
exportContent += " pluginReactConfig,\n";
importContent += "import { fixupConfigRules } from \"@eslint/compat\";\n";
exportContent += " ...fixupConfigRules(pluginReactConfig),\n";
}
if (this.answers.config) {
const config = this.answers.config;
Expand All @@ -179,7 +182,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 +213,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 +248,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.2.0",
"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.2.0",
"globals",
"@eslint/js",
"typescript-eslint",
"eslint",
],
"installFlags": [
"-D",
],
}
10 changes: 8 additions & 2 deletions tests/__snapshots__/problems-commonjs-react-javascript
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,25 @@
"configContent": "import globals from "globals";
import pluginJs from "@eslint/js";
import pluginReactConfig from "eslint-plugin-react/configs/recommended.js";
import { fixupConfigRules } from "@eslint/compat";


export default [
{files: ["**/*.js"], languageOptions: {sourceType: "commonjs"}},
{languageOptions: { globals: {...globals.browser, ...globals.node} }},
pluginJs.configs.recommended,
pluginReactConfig,
...fixupConfigRules(pluginReactConfig),
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint@^9.2.0",
"globals",
"@eslint/js",
"eslint-plugin-react",
"eslint",
"@eslint/compat",
],
"installFlags": [
"-D",
"--force",
],
}
10 changes: 8 additions & 2 deletions tests/__snapshots__/problems-commonjs-react-typescript
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,27 @@
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
import pluginReactConfig from "eslint-plugin-react/configs/recommended.js";
import { fixupConfigRules } from "@eslint/compat";


export default [
{files: ["**/*.js"], languageOptions: {sourceType: "commonjs"}},
{languageOptions: { globals: {...globals.browser, ...globals.node} }},
pluginJs.configs.recommended,
...tseslint.configs.recommended,
pluginReactConfig,
...fixupConfigRules(pluginReactConfig),
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint@^9.2.0",
"globals",
"@eslint/js",
"typescript-eslint",
"eslint-plugin-react",
"eslint",
"@eslint/compat",
],
"installFlags": [
"-D",
"--force",
],
}
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.2.0",
"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.2.0",
"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.2.0",
"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.2.0",
"globals",
"@eslint/js",
"typescript-eslint",
"eslint",
],
"installFlags": [
"-D",
],
}
10 changes: 8 additions & 2 deletions tests/__snapshots__/problems-esm-react-javascript
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,24 @@
"configContent": "import globals from "globals";
import pluginJs from "@eslint/js";
import pluginReactConfig from "eslint-plugin-react/configs/recommended.js";
import { fixupConfigRules } from "@eslint/compat";


export default [
{languageOptions: { globals: {...globals.browser, ...globals.node} }},
pluginJs.configs.recommended,
pluginReactConfig,
...fixupConfigRules(pluginReactConfig),
];",
"configFilename": "eslint.config.js",
"devDependencies": [
"eslint@^9.2.0",
"globals",
"@eslint/js",
"eslint-plugin-react",
"eslint",
"@eslint/compat",
],
"installFlags": [
"-D",
"--force",
],
}