-
Notifications
You must be signed in to change notification settings - Fork 29.3k
Support eslint flat config #56181
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
Closed
Closed
Support eslint flat config #56181
+64
−32
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
AlexisSossa
suggested changes
Nov 14, 2023
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi maybe this works!!
// Function to load ESLint dependencies and check if ESLint is installed
async function loadESLintDependencies(baseDir) {
const deps = await hasNecessaryDependencies(baseDir, requiredPackages);
if (deps.missing.some((dep) => dep.pkg === 'eslint')) {
throw new Error(`ESLint is not installed. Please install ESLint in your project.`);
}
return deps;
}
// Function to get the ESLint module and its associated unsupported API
async function getESLintModule(baseDir) {
const deps = await loadESLintDependencies(baseDir);
const modPath = deps.resolved.get('eslint');
const unsupportedApiPath = path.resolve(path.dirname(modPath), './unsupported-api.js');
const mod = require(modPath);
const unsupportedApi = require(unsupportedApiPath);
return { mod, unsupportedApi };
}
// Function to determine the configuration type for ESLint
async function determineConfigType({ mod, unsupportedApi }) {
let shouldUseFlatConfig = await unsupportedApi.shouldUseFlatConfig();
return shouldUseFlatConfig ? unsupportedApi.FlatESLint : mod.ESLint;
}
// Function to configure ESLint with the appropriate options
async function configureESLint(baseDir, opts) {
const { mod, unsupportedApi } = await getESLintModule(baseDir);
const ESLint = await determineConfigType({ mod, unsupportedApi });
const eslintVersion = ESLint.version ?? mod.CLIEngine.version;
if (!eslintVersion || semver.lt(eslintVersion, '7.0.0')) {
throw new Error(`Your project is using an older version of ESLint (${eslintVersion}). Please upgrade to version 7 or above.`);
}
let options = getESLintOptions(unsupportedApi, opts);
return new ESLint(options);
}
// Function to get ESLint options based on configuration type
function getESLintOptions(unsupportedApi, opts) {
let shouldUseFlatConfig = unsupportedApi.shouldUseFlatConfig();
return {
baseConfig: {},
...(!shouldUseFlatConfig ? {
useEslintrc: true,
errorOnUnmatchedPattern: false,
extensions: ['.js', '.jsx', '.ts', '.tsx'],
cache: true,
...opts.eslintOptions,
} : {}),
};
}
// Main function to handle the linting process
async function mainLintFunction(baseDir, opts) {
try {
const eslint = await configureESLint(baseDir, opts);
// Rest of the linting logic here...
} catch (error) {
Log.error(error.message);
return null;
}
}
// Main execution
mainLintFunction(baseDir, opts);
Close this PR for now. Anyone who needs it can patch Here is a patch example: diff --git a/dist/lib/eslint/runLintCheck.js b/dist/lib/eslint/runLintCheck.js
index 080bd27878721805f16d104255ba4a8b1a9a1410..ab431e64e746f97ef23ba799c20005a3caf728fe 100644
--- a/dist/lib/eslint/runLintCheck.js
+++ b/dist/lib/eslint/runLintCheck.js
@@ -122,34 +122,56 @@ async function lint(baseDir, lintDirs, eslintrcFile, pkgJsonPath, { lintDuringBu
_log.error(`ESLint must be installed${lintDuringBuild ? " in order to run during builds:" : ":"} ${(0, _picocolors.bold)((0, _picocolors.cyan)((packageManager === "yarn" ? "yarn add --dev" : packageManager === "pnpm" ? "pnpm install --save-dev" : "npm install --save-dev") + " eslint"))}`);
return null;
}
- const mod = await Promise.resolve(require(deps.resolved.get("eslint")));
- const { ESLint } = mod;
+ const modPath = deps.resolved.get('eslint')
+ const unsupportedApiPath = _path.default.resolve(
+ _path.default.dirname(modPath),
+ './unsupported-api.js'
+ )
+
+ const mod = await Promise.resolve(require(modPath))
+ const unsupportedApi = await new Promise((resolve) => {
+ try {
+ resolve(require(unsupportedApiPath))
+ } catch (err) {
+ resolve(null)
+ }
+ })
+
+ let { ESLint } = mod
+ let shouldUseFlatConfig = false
+ if (unsupportedApi) {
+ shouldUseFlatConfig = await unsupportedApi.shouldUseFlatConfig?.()
+ if (shouldUseFlatConfig) {
+ ESLint = unsupportedApi.FlatESLint
+ }
+ }
+
let eslintVersion = (ESLint == null ? void 0 : ESLint.version) ?? ((_mod_CLIEngine = mod.CLIEngine) == null ? void 0 : _mod_CLIEngine.version);
if (!eslintVersion || _semver.default.lt(eslintVersion, "7.0.0")) {
return `${(0, _picocolors.red)("error")} - Your project has an older version of ESLint installed${eslintVersion ? " (" + eslintVersion + ")" : ""}. Please upgrade to ESLint version 7 or above`;
}
let options = {
- useEslintrc: true,
baseConfig: {},
- errorOnUnmatchedPattern: false,
- extensions: [
- ".js",
- ".jsx",
- ".ts",
- ".tsx"
- ],
- cache: true,
- ...eslintOptions
+ ...(!shouldUseFlatConfig
+ ? {
+ useEslintrc: true,
+ errorOnUnmatchedPattern: false,
+ extensions: ['.js', '.jsx', '.ts', '.tsx'],
+ cache: true,
+ ...eslintOptions,
+ }
+ : {}),
};
let eslint = new ESLint(options);
let nextEslintPluginIsEnabled = false;
const nextRulesEnabled = new Map();
+
for (const configFile of [
eslintrcFile,
pkgJsonPath
]){
var _completeConfig_plugins;
- if (!configFile) continue;
+ if (!configFile || shouldUseFlatConfig) continue;
const completeConfig = await eslint.calculateConfigForFile(configFile);
if ((_completeConfig_plugins = completeConfig.plugins) == null ? void 0 : _completeConfig_plugins.includes("@next/next")) {
nextEslintPluginIsEnabled = true;
@@ -189,8 +211,10 @@ async function lint(baseDir, lintDirs, eslintrcFile, pkgJsonPath, { lintDuringBu
eslint = new ESLint(options);
}
} else {
- _log.warn("");
- _log.warn("The Next.js plugin was not detected in your ESLint configuration. See https://nextjs.org/docs/basic-features/eslint#migrating-existing-config");
+ if (!shouldUseFlatConfig) {
+ _log.warn("");
+ _log.warn("The Next.js plugin was not detected in your ESLint configuration. See https://nextjs.org/docs/basic-features/eslint#migrating-existing-config");
+ }
}
const lintStart = process.hrtime();
let results = await eslint.lintFiles(lintDirs);
@@ -237,7 +261,8 @@ async function runLintCheck(baseDir, lintDirs, opts) {
".eslintrc.yaml",
".eslintrc.yml",
".eslintrc.json",
- ".eslintrc"
+ ".eslintrc",
+ "eslint.config.js"
], {
cwd: baseDir
}) ?? null; |
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
According to the doc from ESLint,
eslint.config.js
is the configuration file format of the next version of eslint, and ESLint's new config system, Part 3: Developer preview mentions how developers should migrate.Therefore, in this PR, I try to make
next lint
can supporteslint.config.js
and execute lint correctly.If I made a mistake, I'll do my best to fix it.