Eslint-plugin-react: Rule proposal: displayName matches filename

Created on 17 Jul 2015  Â·  19Comments  Â·  Source: yannickcr/eslint-plugin-react

As often happens in code copy-pasting, some component invariably has a displayName copied from another file.

It'd be fantastic to have a rule that requires the component name match the filename.

Positive tests:

  • Foo.js: React.createClass({ displayName:"Foo", ... })
  • Foo.jsx: React.createClass({ displayName:"Foo", ... })
  • Foo.es: React.createClass({ displayName:"Foo", ... })
  • FooComponent.jsx: React.createClass({ displayName:"FooComponent", ... })
  • Foo.js: React.createClass({ ... }) // no displayName specified — validated by separate rule

Negative tests:

  • FooComponent.js: React.createClass({ displayName:"Foo", ... })
  • Bar.js: React.createClass({ displayName:"Foo", ... })
  • Bar.js: React.createClass({ displayName:"", ... })
new rule

Most helpful comment

The same naming convention should apply to an SFC as to a class component.

All 19 comments

:+1: Should probably take into account no-multi-comp and be an option of the display-name rule.

Isn't the displayName automatically set by the JSX transformer? I've never set it manually on React.createClass-style React components.

I got this done with https://github.com/selaux/eslint-plugin-filenames (as soon as you use export default), seems to be a better solution, as it's react-agnostic

@benjamine that plugin seems to not work with .jsx files, which is kind of a nonstarter.

@ljharb I know it says that, but I'm using it in a .jsx and works fine.

A related rule proposal: could we have a rule to component variable name matches filename?

It would be also nice to be able to enforce that component name matches parent folders too.

Maybe it could have a parameter to choose naming convention.

For this scenario, an example:

  • Filename: src/components/Foo/Bar.js
  • Valid:
class FooBar extends React.PureComponent {}
  • Invalid:
class Foo extends React.PureComponent {}

I would expect that component to be named Bar, not FooBar, but yes, that seems useful.

Vue has this plugin https://eslint.vuejs.org/rules/match-component-file-name.html

Would love to see a rule like this for React.

If there is interest, I would love to adjust the rule I developed for my current company. It ended up enforcing a file structure (which I would be happy to share too), but a general solution could disambiguate the parent folders as a part of the name is to receive a regex flag with the desired folder as matching groups, like the following example:

const regexFlag = `src/components(/${PascalCaseRegex}){1,2}.js`

I'm pretty against using a regex in a linting config, but if you can think of alternatives i'm all ears.

For what it's worth I don't personally need this anymore since my development environment has since changed (I now use functional components and TypeScript).

The same naming convention should apply to an SFC as to a class component.

Hmm, then maybe having a matchParentFoldersByCase flag which tells the matched folders by its case type, and also a blacklist?

In my current modular structure, the most complex pattern a file could have is the following: src/modules/Foo/Bar/components/Baz/index.js, and then the component name should be FooBarBaz.

In the above examples, all the matched folders are in PascalCase, for instance.

I'm not sure I understand the logic there; I'd still call that a Baz.

Then this flag wouldn't be present and would match the filename only. It's just a way to also attend other naming conventions.

The same naming convention should apply to an SFC as to a class component.

Agree.

So would this rule be about ensuring consistent naming all around? Considering:

  • var name
  • export name
  • component function name
  • component class name
  • component display name
  • file name, or if exported from index.*, the folder name? Or maybe there should be a config option to only look at dir name?

The only name that matters is the eventual displayName of the react component. Thus, the variable name shouldn't matter (unless it's the one that's inferred).

Separately, I'd expect a component to either be a default export (the name doesn't matter) or a named export with the same name as the display name.

@ljharb thats true but there are plugins which transform var name to displayName such as

https://babeljs.io/docs/en/babel-plugin-transform-react-display-name

For the old createClass pattern, yes, but that's not something that's reasonable for this lint rule to know about.

Was this page helpful?
0 / 5 - 0 ratings