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

4.0 eslint-config-norton fixes/tweaks #39

Merged
merged 34 commits into from
Sep 4, 2020
Merged

4.0 eslint-config-norton fixes/tweaks #39

merged 34 commits into from
Sep 4, 2020

Conversation

sh0ji
Copy link
Contributor

@sh0ji sh0ji commented Aug 28, 2020

After installing eslint-config-norton@4.0.0-beta.2 in a couple projects, I noticed that semicolons were no longer being enforced because of the use use of eslint-config-prettier. I ended up digging into the 4.0 config a bit more and found some other issues that I've fixed here.

The commit messages/bodies cover the changes in more detail but here's an overview:

  • custom rules were listed before the prettier config in the "extends," which caused the prettier opinions to override ours. Custom rules have to come last in the list.
  • the React rules had some redundancies and some rules that aren't included in the style guide. I've simplified it quite a bit.
  • the TypeScript parserOptions is highly dependant on the project details so I removed it here (the existing config caused issues in the design system, for instance). This should be documented but eslint does output a clear error and directions when you haven't configured it in your project.
  • split out base typescript rules from react typescript so that only the base rules are used in the "base" config, which has been updated.
  • added tests for all custom rules, which are being explicitly tested against vanilla js, react, typescript, and typescript+react.

- separate pure typescript rules from typescript+react rules
- remove parserOptions from the config (this has to be set by the project)
- add import/resolver settings for node & webpack
This is already included by extending eslint-config-airbnb/hooks.
this could potentiatlly break projects that are using the config but aren't using browser globals. it should be set in the project's eslintrc.
- jsx-filename-extension is already set to .jsx by eslint-config-airbnb (.tsx should be added by the typescript override)
- jsx-props-no-spreading is part of airbnb and should only be disabled on a case-by-case basis
- static-property-placement must be the default since 'static public field' isn't supported by most compilers (it's turned on in the typescript config)
- the two react-hooks rules are set by extending `eslint-config-airbnb/hooks`
this allows us to remove the esm dev dependency
@sh0ji sh0ji requested a review from ParmeJon August 28, 2020 22:51
@ParmeJon
Copy link
Contributor

ParmeJon commented Sep 1, 2020

This is great! thanks for looking into the Eslint more Evan.

Prettier

  • The prettier rules were put on the bottom since eslint-config-norton is meant to be used with prettier-config-norton. The semicolons are enforced/added in from prettier-config-norton instead. But I guess it doesn't hurt to include the custom rules below so it can work alone better. At the time I thought it'd be cleaner where I made eslint-config-norton completely avoid any rules related to what prettier handles.

React

  • Thank you! The reduced React file definitely looks cleaner. The react-hooks plugin is being used in the extended airbnb file anyways.

Typescript

  • Ah the parserOptions was a bit confusing to me.
  • Thank you for splitting base typescript from react typescript. That definitely should be the case.

Tests

  • Amazing. :)

@ParmeJon
Copy link
Contributor

ParmeJon commented Sep 1, 2020

I've faced an issue regarding the eslint-config-norton overrides file for TypeScript linting.

When using @typescript-eslint as a plugin in the overrides file I get a:

message: `Failed to load plugin '@typescript-eslint' declared in '.eslintrc.js » ./packages/eslint-config-norton#overrides[0]': Cannot find module 'typescript'

upon running the lint command from the application side where Typescript is not being used.

This presents an interesting problem. Overrides were implemented to be flexible where they only effect file extensions that are expected. However they still track their imports and dependencies and since this overrides file uses @typescript-eslint which has a dependency on typescript and typescript wasn't being used in my project, the lint command triggers an error.

@sh0ji

@sh0ji
Copy link
Contributor Author

sh0ji commented Sep 1, 2020

eslint-config-prettier only turns rules off (see https://github.com/prettier/eslint-config-prettier/blob/master/index.js to see exactly what rules it turns off). And now that I think about it, I wonder if it's even a good idea to use it since it effectively changes the style guide. The semicolon issue was the only one I noticed but looking through that config, there should be other discrepancies.

As I understand it, there are really two options for prettier:

  1. Include eslint-config-prettier and modify the style guide to remove all of the rules that Prettier disables.
  2. Don't include eslint-config-prettier and tell developers to not use Prettier to format js/ts.
    • This is my preferred approach and it's what I do with the Design System. I do this by simply not including .js/.ts in the prettier script glob.
    • Also note that while Prettier is a better general-purpose code formatter than ESLint (Prettier can format a ton of languages quite well), ESLint is better at formatting js/ts.

@sh0ji
Copy link
Contributor Author

sh0ji commented Sep 1, 2020

I've faced an issue regarding the Typescript overrides file.

When using @typescript-eslint as a plugin in the overrides file I get a:

message: `Failed to load plugin '@typescript-eslint' declared in '.eslintrc.js » ./packages/eslint-config-norton#overrides[0]': Cannot find module 'typescript'

upon running the lint command from the application side where Typescript is not being used.

This presents an interesting problem. Overrides were implemented to be flexible where they only effect file extensions that are expected. However they still track their imports and dependencies and since this overrides file uses @typescript-eslint which has a dependency on typescript and typescript wasn't being used in my project, the lint command triggers an error.

@sh0ji

This is a great point. I can think of two reasons why including typescript as a dependency would be a bad idea.

  1. It would be extraneous in projects that don't use TypeScript.
    • To my mind, this is a very serious issue even though its impact in isolation might be relatively minimal. Library maintainers need to be diligent about reducing dependency bloat and this is an instance where we would knowingly increase it.
  2. Projects that do use TypeScript would potentially have two versions in their tree.

With that in mind, I would propose switching fully to an "entrypoint" approach along with listing typescript as optional in peerDependenciesMeta (note that this npm feature is currently undocumented in package.json but it landed in npm v6.11.0).

The entrypoint approach is how nearly every major ESLint config works and I'm reluctant to reinvent the wheel for our config. For instance:

@ParmeJon
Copy link
Contributor

ParmeJon commented Sep 1, 2020

eslint-config-prettier only turns rules off (see https://github.com/prettier/eslint-config-prettier/blob/master/index.js to see exactly what rules it turns off). And now that I think about it, I wonder if it's even a good idea to use it since it effectively changes the style guide. The semicolon issue was the only one I noticed but looking through that config, there should be other discrepancies.

As I understand it, there are really two options for prettier:

  1. Include eslint-config-prettier and modify the style guide to remove all of the rules that Prettier disables.

  2. Don't include eslint-config-prettier and tell developers to not use Prettier to format js/ts.

    • This is my preferred approach and it's what I do with the Design System. I do this by simply not including .js/.ts in the prettier script glob.
    • Also note that while Prettier is a better general-purpose code formatter than ESLint (Prettier can format a ton of languages quite well), ESLint is better at formatting js/ts.

Hmm interesting point. However I feel like we can just adjust the options in Prettier to match our style guides. This is what was originally intended and implemented. The comma-dangle discrepancy was definitely missed at the time and possibly more. Are there any examples as to how ESLint is better at formatting js/ts than Prettier?

If we use Prettier, for me, I think it'd be easier to stick to one way of formatting using Prettier across as many languages as we can. Leads to less gotchas? Which is why I am shying away from the second option. Unless ESLint has a strong "betterness" than Prettier in regards to js and ts.

@ParmeJon ParmeJon merged commit 466aca2 into main Sep 4, 2020
Copy link

@LUGO022 LUGO022 left a comment

Choose a reason for hiding this comment

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

I

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants