With the release of Create React App 3, we now have the ability to use absolute import paths, without ejecting.
If you’re reading this you probably don’t need me to tell you why this is a good thing. I’m going to anyway, though.
- It’s easier to type out the paths, no more ../../../hell.
- You can copy/paste code including imports into other files and not have to fiddle with the import paths.
- You can move a file without having to update its input paths (if you IDE doesn’t do that for you anyway).
- It’s neat.
That’s an absolute path
As explained in the docs, you start by creating a jsconfig.json file in your root with these characters and symbols in it:
That’s great, now you can take something like this:
And make those imports prettier.
Unfortunately, this is where the docs stop. But you might not be done just yet.
If you’re a WebStorm/IntelliJ user, you’re going to hear some complaints:
WebStorm assumes absolute paths are in node_modules (as per the Node.js rules), so we must tell it that we’re being fancy and using absolute imports.
First up, mark the src directory as a Resources Root.
Love a menu with 31 things in it
So now Webstorm understands where those absolute paths are pointing. This means no warnings, and jump-to-source/autocomplete will work. It also means absolute paths will be used by the auto-import mechanism.
So if I have this file:
And I paste this code into it:
WebStorm will know I need <Button> and STRINGS and LINKS and insert the appropriate imports with the absolute paths.
Unfortunately it doesn’t sort them the way I want to (npm packages first, relative imports last). Maybe this is possible and I just can’t work out how.
But still, I’d rather have to re-order imports than type them out like a Denisovan.
VS Code — no config required
VS Code understands jsconfig.json files out of the box, so ‘jump to source’ and Intellisense will work just fine with absolute imports.
And it doesn’t seem to care if you have an import path pointing to a file that doesn’t exist, so no config required there either.
(Side note: as of May 2019, WebStorm is still better than VS Code IMO. It has vastly superior git tools — particularly for conflict resolution — and is better for refactoring. But VS Code is catching up fast, and opens in a tenth the time.)
Capital letters by convention
Absolute paths have been possible for a long time with Webpack, and it has become convention to use PascalCase for your aliased import roots (this is how it’s done in the examples from the Webpack docs).
This is smart, and I would recommend doing the same in your codebase by renaming all your top-level directories to PascalCase.
When things like Components and Utils start with capital letters, it will be plain to see which imports are npm packages and which are your own source code. You’ll also never have a clash with an npm package.
For similar reasons, avoid files stored in the root of src that you’re going to be importing. For example, if you had src/constants.js, you’d have to do import constants from 'constants'; which is just odd.
CRA has a very minimal set of rules in their ESLint setup, and some strong opinions about why this is the case. If you’re clever like me, you’ll disregard the advice of Facebook (what do they know about React anyway?) and use something like Airbnb’s ESLint config.
If you do, you will soon learn that Airbnb use eslint-plugin-import, which checks for undefined imports, and will give you errors like so:
You can fix this with a settings prop in your ESLint config to tell it that your paths might be relative to src:
Note that you don’t need to install any npm package for this, that settings chunk is enough.
Side note, since we’re talking about ESLint: Do you use Prettier? You should. I think some people are drawn in by the promises made by the name, but turned off when they realise that a more fitting name would have been ‘Uglier’.
Yes, sometimes it behaves like a madman tearing up a Monet to mail it, maniacally grunting: Must. Fit. In. Envelope. But once you accept that it’s going to make your pretty code look pretty gross in places, you can build a bridge, get over it, and move on to reap the rewards: not discussing code style with other developers.
Absolute imports are a little bit of magic that might confuddle a new developer for a moment, so I suggest putting a few lines in your readme about what’s going on, including notes about IDE setup. You might even link to this post, and I totally promise I’m not going to change the content a year from now to be nothing but pictures of ducks, sorted by age.
It’s also worth defining when a developer should still use relative imports. I think it’s reasonable to say that sibling files should be imported with a relative path, but not anything where you need to go up the tree. And I’d suggest using relative imports for closely related child components. If you have a <Dropdown> with a <DropdownItem> child component, it’s probably overkill to use a full absolute path to import DropdownItem.
Hey that was a pretty short post!
Have a spectacular day my internet friends.