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

Deprecate import-index rule #1787

Merged
merged 2 commits into from Apr 2, 2022

Conversation

fisker
Copy link
Collaborator

@fisker fisker commented Apr 2, 2022

No description provided.

@sindresorhus sindresorhus merged commit 0034e69 into sindresorhus:main Apr 2, 2022
@fisker fisker deleted the remove-import-index branch April 2, 2022 09:43
@kachkaev
Copy link
Contributor

kachkaev commented Apr 2, 2022

@fisker WDYT of a rule that bans index.{js,ts}{,x} files? I am currently using canonical/filename-no-index, but it’d be much cooler to have this rule in unicorn too!

I know that it's better to discuss such things in a new issue – this is just a quick sense-check.

@fisker
Copy link
Collaborator Author

fisker commented Apr 3, 2022

I don't know, I alway use index.js like this https://github.com/sindresorhus/eslint-plugin-unicorn/blob/main/rules/selectors/index.js

@fisker
Copy link
Collaborator Author

fisker commented Apr 3, 2022

Maybe only allow re-export in index.js?

@kachkaev
Copy link
Contributor

kachkaev commented Apr 3, 2022

I used to use index.js to re-export stuff for a while. This was my typical dev flow:

  1. Create foo.js
  2. Add code
  3. Realise that foo.js is too big
  4. Replace the file with foo/index.js which re-exports foo/bar.js, foo/baz.js, etc.

The problem with this approach is that the last step is quite tedious. It’s not only necessary to delete the original file, but also to think about filenames in the subfolder. It is not always easy to come up with nice mini-groups to avoid actual code in foo/index.js.

Another problem with foo/index.js is that it can’t be imported the same way as foo.js, unless we rely on the Node.js resolution mechanism. Pure ESM modules don’t support import { foo } from "./foo"; — it has to be either import { foo } from "./foo.js"; or import { foo } from "./foo/index.js";.

So I’ve decided to ban index.js completely and here is what I do now:

  1. Create foo.js
  2. Add code
  3. Realise that foo.js is too big
  4. Create foo folder and place foo/bar.js into it.
  5. Add import { bar } from "./foo/bar.js" in foo.js. Keep existing code in foo.js as long as I’m happy with the file size.

Thus, foo.js works as the stable ‘entry point’ for foo and foo folder contains ‘private’ stuff that can only be imported from foo.js. Other files can only import from ./foo.js (as if it’s a local mini-npm library), but they must never look into files like ./foo/bar.js. That would be like calling a private method of a class.

What’s cool is that an upgrade from foo.js into foo.js + foo/*.* is no longer a ‘revolution’. The transition feels very natural and does not stand on my way.

This approach is inspired by https://github.com/benawad/destiny — see this youtube talk. If you want to check out an example file structure, here are a couple of public projects I’ve got using it:

All this is still experimental. Curious to hear your thoughts!

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.

None yet

3 participants