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: Avoid dirname for built-in configs. #15602

Closed
wants to merge 2 commits into from
Closed

Conversation

daidodo
Copy link
Contributor

@daidodo daidodo commented Feb 13, 2022

Load eslint:recommended and eslint:all configs via import instead file paths.

Fixes: #15575

Prerequisites checklist

What is the purpose of this pull request? (put an "X" next to an item)

  • Documentation update
  • Bug fix (template)
  • New rule (template)
  • Changes an existing rule (template)
  • Add autofix to a rule
  • Add a CLI option
  • Add something to the core
  • Other, please explain: Avoid using __dirname for built-in configs, i.e. eslint:recommended and eslint:all.

What changes did you make? (Give an overview)

I made changes to cli-engine.js and file-enumerator.js to pass in built-in config objects directly instead of file paths.

Is there anything you'd like reviewers to focus on?

The main changes are in @eslint/eslintrc package (PR).
It should be merged and released first before changes here can be applied.

Load eslint:recommended and eslint:all configs via import instead file paths.

Fixes: eslint#15575
@eslint-github-bot eslint-github-bot bot added triage An ESLint team member will look at this issue soon bug ESLint is working incorrectly labels Feb 13, 2022
@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Feb 13, 2022

CLA Not Signed

@daidodo
Copy link
Contributor Author

daidodo commented Feb 14, 2022

The build failed because the main changes are in @eslint/eslintrc package (eslint/eslintrc#70).
It should be merged and released first before changes here can be applied.

@mdjermanovic mdjermanovic added core Relates to ESLint's core APIs and features evaluating The team will evaluate this issue to decide whether it meets the criteria for inclusion and removed triage An ESLint team member will look at this issue soon labels Feb 14, 2022
@@ -19,7 +19,8 @@ const fs = require("fs");
const path = require("path");
const defaultOptions = require("../../conf/default-cli-options");
const pkg = require("../../package.json");

const eslintRecommendedConfig = require("../../conf/eslint-recommended.js");
const eslintAllConfig = require("../../conf/eslint-all.js");
Copy link
Member

Choose a reason for hiding this comment

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

This would always load all core rules, which we try to avoid. Could we instead pass to new CascadingConfigArrayFactory() a function that loads these modules when called?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for reviewing the PR!

May I ask why we try to avoid that? If it's for performance, is there a benchmark?
The point of the change is to avoid use of __dirname by resolving the configs before packaging (e.g. webpack) because __dirname harms usability of ESLint library and disallows webpacking.

Copy link
Member

Choose a reason for hiding this comment

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

Yes, it's only for performance reasons. It's observable from the "Loading" test when you run npm run perf script.

However, this revealed that we have another place where eslint-all.js is unconditionally loaded, so if you'd like to see the difference in performance locally, you'd need to apply the change from #15606 first.

Copy link
Member

Choose a reason for hiding this comment

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

The point of the change is to avoid use of __dirname by resolving the configs before packaging (e.g. webpack) because __dirname harms usability of ESLint library and disallows webpacking.

Would webpack be able to include those two modules if they're require-d in a function?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried dynamic import and require but got errors in eslintrc/lib/flat-compat.js:

class FlatCompat {

    constructor({
        baseDirectory = process.cwd(),
        resolvePluginsRelativeTo = baseDirectory
    } = {}) {
        this.baseDirectory = baseDirectory;
        this.resolvePluginsRelativeTo = resolvePluginsRelativeTo;
        this[cafactory] = new ConfigArrayFactory({
            cwd: baseDirectory,
            resolvePluginsRelativeTo,
            eslintAllPath: path.resolve(dirname, "../conf/eslint-all.cjs"),
            eslintRecommendedPath: path.resolve(dirname, "../conf/eslint-recommended.cjs"),
+           eslintAllConfig: () => import("../conf/eslint-all.cjs"),    // 'import()' expressions are not supported yet. eslint[node/no-unsupported-features/es-syntax]
+           eslintRecommendedConfig: () => require("../conf/eslint-recommended.cjs")  // 'require' is not defined. eslint[no-undef]
        });
    }
//...

Hope someone can help me with the issues. Thanks!

Copy link
Member

Choose a reason for hiding this comment

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

Since after this change those two configurations no longer need to be in files, we can inline their content directly in flat-compat.js and delete those .cjs files.

class FlatCompat {

    constructor({
        baseDirectory = process.cwd(),
        resolvePluginsRelativeTo = baseDirectory
    } = {}) {
        this.baseDirectory = baseDirectory;
        this.resolvePluginsRelativeTo = resolvePluginsRelativeTo;
        this[cafactory] = new ConfigArrayFactory({
            cwd: baseDirectory,
            resolvePluginsRelativeTo,
            getEslintAllConfig: () => ({
                settings: {
                    "eslint:all": true
                }
            }),
            getEslintRecommendedConfig: () => ({
                settings: {
                    "eslint:recommended": true
                }
            })
        });
    }

(I think it's better to name the new properties getEslintAllConfig and getEslintRecommendedConfig, to make clear that they're functions).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks!

I've updated both PRs to address the comments.

Load eslint:recommended and eslint:all configs via import instead file paths.

Fixes: eslint#15575
@daidodo
Copy link
Contributor Author

daidodo commented Feb 16, 2022

I've created new PRs (eslint/eslintrc#71 and #15616) to address the comments and with clean commit histories. So closing this PR.

Sorry for the inconvenience!

@daidodo daidodo closed this Feb 16, 2022
@eslint-github-bot eslint-github-bot bot locked and limited conversation to collaborators Aug 16, 2022
@eslint-github-bot eslint-github-bot bot added the archived due to age This issue has been archived; please open a new issue for any further discussion label Aug 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
archived due to age This issue has been archived; please open a new issue for any further discussion bug ESLint is working incorrectly core Relates to ESLint's core APIs and features evaluating The team will evaluate this issue to decide whether it meets the criteria for inclusion
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Bug: ESLint API cannot find eslint-recommended.js
3 participants