If you have worked on a decently sized Node.js application regardless of whether its JavaScript or TypeScript, you will have come across long imports such as these:
import User from "../../../../models/User";
which made you go:
Rewriting long imports hundreds of times can get on anyone's nerves. This article with show you how to compress those long imports into compact and short imports. After all:
Shorter Code == Happier Devs π
Enter jsconfig.json
What is jsconfig.json
? you might be asking. Well, jsconfig.json
can be thought of as a descendent of tsconfig.json
, with the allowJs
attribute set to true
.
In simple terms, jsconfig.json
is a file that specifies that the directory is the root of a JavaScript project. The tsconfig.json
& jsconfig.json
file specifies the root files and the compiler options required to compile the project.
For more on jsconfig.json
, check out this article.
For Demonstration purpose, we would be working on a demo project with the following file structure:
.
β app.js
β jsconfig.json
β package.json
β
ββββmodels
β user.js
β
ββββutils
ββββcolors
β converter.js
β generateColor.js
β
ββββdatetime
formatter.js
timezoneHelpers.js
Base Url
The easiest way to get rid of the long imports is to add baseUrl
in the jsconfig.json
(add jsconfig.json
at the root level of the project in case you don't have it).
{
"compilerOptions": {
"baseUrl": "."
}
}
Viola! Now you can directly access the files and folders at the root level of your project. So to import color related functions in the User model, you can now use:
import { hexToRgb, rgbToHex } from 'utils/colors/converter'
in place of:
import { hexToRgb, rgbToHex } from '../utils/colors/converter'
That's just a minor improvement in this demo, but in case your project has a lot of nested folders, it would lead to significant reductions.
But let's try to do better.
Paths
Paths allow us to aggregate a list directories under a predefined name and drastically reduce the length of the imports.
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@models/*": [
"./models/*"
],
"@colors/*": [
"./utils/colors/*"
],
"@datetime/*": [
"./utils/datetime/*"
]
}
}
}
We are aggregating all the files in the models
folder under the name @models
. The same is the case for colors
and datetime
. We would be able to reference the folders using @models
, @colors
, and @datetime
in the import statement. So,
import { hexToRgb, rgbToHex } from '../utils/colors/converter'
finally reduces to:
import { hexToRgb, rgbToHex } from '@colors/converter'
Somethings worth noting:
- The
pathname
doesn't have to be the same as the actual folder name. But it's a good idea to keep them the same to avoid confusion. -
You can aggregate as many folders you want under any
pathname
. Let's take a look at a bit absurd example:
"@colors/*": [ "./utils/colors/*", "./utils/datetime/*" ]
This would result in both the datetime and colors folders to be aggregated under the name
@colors
.
TypeScript
Everything we went over can be used with TypeScript as well. Just replace jsconfig.json
with tsconfig.json
and you are done.
NOTE: As TalOrlanczyk pointed out in the comments, this doesn't work with create-react-app
. The work-around is provided in the comments below.
Wrapping up
This article went through how to optimize the annoying long imports into concise small statements. I hope this helps you in your development journey! :)
Finding personal finance too intimidating? Checkout my Instagram to become a Dollar Ninja
Thanks for reading
Want to work together? Contact me on Upwork
Want to see what I am working on? Check out my GitHub
I am a freelancer who will start off as a Digital Nomad in mid-2022. Want to catch the journey? Follow me on Instagram
Follow my blogs for weekly new tidbits on Dev
FAQ
These are a few commonly asked questions I get. So, I hope this FAQ section solves your issues.
-
I am a beginner, how should I learn Front-End Web Dev?
Look into the following articles: Would you mentor me?
Sorry, I am already under a lot of workload and would not have the time to mentor anyone.Would you like to collaborate on our site?
As mentioned in the previous question, I am in a time crunch, so I would have to pass on such opportunities.
Connect to me on
Top comments (16)
subpath patterns can also be used in package.json. I like to think of it as a cool free feature baked right in to nodejs.
For example:
This way, it's tied to the node project, which will work no matter what the IDE is.
Thanks a lot for sharing! I wasn't aware of this feature
Its great but unfortunately react by itse will ignore paths
I read somewhere it only doesnβt work for create-react-app, did you test it on CRA?
Since this is quite a useful trick, even though it doesn't work directly, there is a work around for it
I think it works with React as well. Tried it in a Next.js project though
For react you need third party library
I tested it right now, it's working with plain old react
weird I copy this exactly and the paths didn't work
the error:Module not found: Can't resolve '@models/tests' in '/Users/talorlanczyk/Projects/react-tests/my-app/src'
I would like you to show me the code on react please
Add the following in
webpack.config.js
:Use
yarn eject
first if you are usingcreate-react-app
Thanks,
But when i say you can't meant that you must do an additional step like eject to do this or use third party library
I think add this to your article will great for a lot of developers
You are π
π
I was using it in angular/nestJS project for a while. I had no idea it was such a big deal.
This works very well for shared libraries in a monorepos.
Yeah, it helps a lot to ease repeatative directory traversal
Absolute path really help me when use typescript. I also make boilerplate for reactjs and typescript with absolute path create-react-typescript-app.vercel...