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

Add option to automatically handle React projects in filename-case rule #203

Open
sindresorhus opened this issue Nov 21, 2018 · 14 comments
Open

Comments

@sindresorhus
Copy link
Owner

The convention for React components is to use pascal case (FooBar.js). We could detect files using JSX and enforce pascal case and ignore the chosen case, but it's also common to have an index.js, routes.js or app-routes.js that has JSX in them, but are not components. So my proposal would be to add an option that, when enabled, would enforce either pascalCase (FooBar.js) or kebabCase (app-routes.js) for files with JSX. I think it would be safe to have it on by default. The option could be called react (Suggestions for a better option name welcome!).

@zeorin
Copy link

zeorin commented Nov 21, 2018

I suggest jsx-filename-case, since it's about JSX (and not React specifically), and filename casing. react is a very broad name.

@sindresorhus
Copy link
Owner Author

@zeorin Options should be in camelcase. jsxFilenameCase is not descriptive enough either I would say.

How about {useJsxConvention: true}?

@zeorin
Copy link

zeorin commented Dec 19, 2018

Ah, I was confused, I thought you were suggesting a new rule name, rather than a new option name (which is indeed a better idea).

Thinking about this a little more, what happens when there are components that start with a lowercase letter? Higher order components do this quite frequently, and whilst most probably don't contain any JSX, we cannot rule that out. Yet it is also a convention.

The term useJsxConvention might imply to some that such nuances would be catered for.

In addition, there might be situations where JSX files have a filename case convention that's different to the rest of the project, but not PascalCase.

How about a new option called jsxCase, that has all the same possible values and behaviours as case? It would override the case option, but only for .jsx files.

"unicorn/filename-case": ["error", {"case": "kebabCase", "jsxCase": "pascalCase"}]

If we also add a new behavior option, false, which switches off checking, then one can have really fine-grained control over the style.

"unicorn/filename-case": ["error", {"case": false, "jsxCase": "pascalCase"}]

@sindresorhus
Copy link
Owner Author

Thinking about this a little more, what happens when there are components that start with a lowercase letter? Higher order components do this quite frequently, and whilst most probably don't contain any JSX, we cannot rule that out. Yet it is also a convention.

Do you have any examples? It would enforce kebabCase (with-router.js) which is sensible.

How about a new option called jsxCase, that has all the same possible values and behaviours as case? It would override the case option, but only for .jsx files.

That doesn't handle the case of JSX files that are not components. Most projects have those, like index.js. (Example).

@MrHen
Copy link
Contributor

MrHen commented Dec 27, 2018

I was under the impression that index.js is always preferred over Index.js because it's a special file name.

I think, at heart, there are slightly different rules being discussed. The idea of switching filename case on extension sounds useful. The idea of detecting JSX usage and switching filename case also sounds useful. Even if they inherently overlap in purpose, it wouldn't be bad to have the chance to choose which of the two fits your project best.

@zeorin
Copy link

zeorin commented Dec 31, 2018

Do you have any examples? It would enforce kebabCase (with-router.js) which is sensible.

That's project-specific. If I'm writing HoCs for a project I might use camelCase, where someone else might opt for kebabCase. Leaving it configurable is what I'd prefer.

That doesn't handle the case of JSX files that are not components. Most projects have those, like index.js. (Example).

I'm assuming this rule doesn't actually inspect the contents of a file for JSX usage, instead simply matching on the file extension; so I assume you meant index.jsx instead of index.js.

I assumed that index.jsx will be hard-coded in this rule to be exactly that: index.jsx, not Index.jsx, as it is a special case. It may make sense to check whether the containing folder adheres to the rule:

"unicorn/filename-case": ["error", {"case": "kebabCase", "jsxCase": "pascalCase"}]
+FooWidget/index.jsx
-foo-widget/index.jsx

If so, it makes sense to add that behaviour to the case option as well as the jsxCase option:

+foo-bar/index.js
-fooBar/index.js

While we're at it we could extend the rule to check the case of any arbitrary file extension, but ESLint's built-in overrides mechanism can achieve the same thing, see my comment on the original issue.

@sindresorhus
Copy link
Owner Author

Just to be clear. This will detect actual JSX usage in a file. Not the .jsx file extension, which is discouraged.

@zeorin
Copy link

zeorin commented Dec 31, 2018

Ah, in that case this is indeed better than using the overrides. I'd still assume index.js to be hard-coded to be excluded from the rule. I feel it's natural to in such a case, apply the rule to the containing directory, but that's only based on my personal experience and may not suit everyone.

In the case of HoCs (that don't start with a capital letter) that follow a different file naming convention and may contain JSX, I feel that either they ought to be in a special directory that can then be catered for using ESLint overrides, or using ESLint configuration comments. Same goes for custom hooks.

@wldcordeiro
Copy link

wldcordeiro commented Feb 4, 2019

Is there a way this rule could apply to directories as well? I like getting this linting across my project to have kebab case but some pascalCase leaks in occasionally from directory names.

@manovotny
Copy link
Contributor

manovotny commented Aug 29, 2019

Our rules allow for both pascal and kebab, but what we want is actually a mix of the two, ie. Button.spec.js.

It'd be nice to not have to capitalize spec just because the filename started with a cap, which feels like a React-esque convention. I don't really recall seeing a Spec in the wild.

Our particular situation could also probably be solved by allowing regex, as mentioned in #343.

@muuvmuuv
Copy link

muuvmuuv commented Mar 3, 2021

Whats about this, is there a workaround?

@fregante
Copy link
Collaborator

fregante commented Mar 9, 2021

If easy, I'd extend the request to support Svelte components (example Svelte project using XO) and Vue (documentation). These might be easier to detect since they have a custom extension, although custom extensions require extra config normally.

@manovotny
Copy link
Contributor

Not sure when / what that changed in eslint-plugin-unicorn, but the following is working well for me now and solves the issues outlined in my previous comment.

'unicorn/filename-case': [
    'error',
    {
        cases: {
            kebabCase: true,
            pascalCase: true,
        }
    }
]

@rtritto
Copy link

rtritto commented Jul 15, 2024

This should support and apply multiple cases by extension:

'unicorn/filename-case': [
  'error',
  {
    cases: {
      kebabCase: {
        extension: '.js'
      },
      pascalCase: {
        extension: '.jsx'
      }
    }
  }
]

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

No branches or pull requests

8 participants