I write a lot of TypeScript. Because I like modularity, I split up my codebases into discreet modules and
import from them as necessary.
Take a look at this
Now take a look at this import:
Which do you prefer? If the answer was "the first" then read no further. You have all you need, go forth and be happy. If the answer was "the second" then stick around; I can help!
There's been a solution for this in TypeScript-land for some time. You can read the detail in the "path mapping" docs here.
Let's take a slightly simpler example; we have a folder structure that looks like this:
We would like
page.tsx to import
'shared/utils' instead of
'../shared/utils'. We can, if we augment our
tsconfig.json with the following properties:
Then we can use option 2. We can happily write:
My code compiles, yay.... Ship it!
Let's not get over-excited. Actually, we're only part-way there; you can compile this code with the TypeScript compiler.... But is that enough?
I bundle my TypeScript with ts-loader and webpack. If I try and use my new exciting import statement above with my build system then disappointment is in my future. webpack will be all like "import whuuuuuuuut?"
You see, webpack doesn't know what we told the TypeScript compiler in the
tsconfig.json. Why would it? It was our little secret.
resolve.alias to the rescue!#
This same functionality has existed in webpack for a long time; actually much longer than it has existed in TypeScript. It's the
So, looking at that I should be able to augment my
webpack.config.js like so:
And now both webpack and TypeScript are up to speed with how to resolve modules.
When I look at the
tsconfig.json and the
webpack.config.js something occurs to me: I don't like to repeat myself. As well as that, I don't like to repeat myself. It's so... Repetitive.
The declarations you make in the
tsconfig.json are re-stated in the
webpack.config.js. Who wants to maintain two sets of code where one would do? Not me.
Fortunately, you don't have to. There's the
tsconfig-paths-webpack-plugin for webpack which will do the job for you. You can replace your verbose
resolve.alias with this:
This does the hard graft of reading your
tsconfig.json and translating path mappings into webpack
aliases. From this point forward, you need only edit the
tsconfig.json and everything else will just work.
Thanks to Jonas Kello, author of the plugin; it's tremendous! Thanks also to Sean Larkin and Stanislav Panferov (of awesome-typescript-loader) who together worked on the original plugin that I understand the
tsconfig-paths-webpack-plugin is based on. Great work!