Importing modules with relative paths can be such a pain as your codebase grows and you start splitting large files into smaller reusable modules. Files get nested very deep so much you stare at your folder structure perplexed. Consider the following folder structure:
root/
tsconfig.json
types.d.ts
.env
src/
server.ts
database/
models/
routes/
posts/
comments/
controllers/
posts/
comments/
media/
utils/
database/
seed.ts
workers/
publisher.ts
Say you want to import a function from a module in src/utils/workers
into the post controller, it's already looking like a mess: import { function } from "../../utils/workers/publisher.ts"
. This can get even messier when file locations change and you need to update everywhere you imported that file.
One way to tackle this is to use typescript path mapping. You define a namespace in your tsconfig mapping it to a specified path by declaring a paths
field in your tsconfig.json
under compilerOptions
like so:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@workers/*": ["src/utils/workers/*"],
"@mediaControllers/*": ["src/controllers/media/*"]
}
}
}
Here, we set the baseUrl to the root directory, which is necessary for creating path maps. We create a namespace "@workers" which maps to the path "src/utils/workers/". The '@' symbol is not necessary, it's just there to easily standout and make it recognizable as a namespace.
Now if we want to import a module from workers
, we simply use the namespace. i.e import { function } from "@workers/publisher.ts"
. We don't have to worry about relative paths anymore, and when we move files from their original location, we just simply update the path map. So problem solved! 😁️.
Note that typescript resolves paths relative to baseUrl
so keep that in mind when creating path maps.
Top comments (7)
The main question is about the naming convention:
workers
? Well sounds like anpm package
name. How to distinguish?@workers
? Well, actually the same - like a package from an org.self/workers
or@self/workers
? Scoped but verbose.There is also one more case - use eslint/tslint to group imports and thus separate something from
node_modules
from your own stuff.But in any case - this is a must-have feature.
The names you choose depends on the way your project is structured. You can also decide to entirely avoid such names that can cause conflicts. It's entirely up to you and that's why the "@" symbol can help distinguish.
Seems like node "imports" dictate the prefix to be "#".
I only just discovered it recently and it's made my life so much easier, not to mention my code looks cleaner too.
VS code automatically updates import paths when you move files...
Doesn't make code more readable 🙂
Typescript does not substitute the correct path so how are you resolving "@workers"?