TypeScript has a cute feature with a small problem causing a huge impact.
Cute Feature: absolute imports with baseUrl
Now you can import all files relative to baseUrl, instead of to the file you’re in! In larger projects this saves you a lot of
import from '../../views' annoyance — you can write
import from 'views' instead, anywhere in your project.
So now your module can’t be imported into other modules
Most build toolchains will have some support but with tradeoffs. So, there are some… workarounds
- Compile your TypeScript with
@babel/typescriptinstead. Drawback: No
.d.tsdefinition files, and no type safety at compile time.
- In a TypeScript parent project, set up your parent (importing) project to resolve imports relative to
tsconfig-paths/register, or manually “absolute to project-root relative” mappings in your parent’s
tsconfig.json. Very manual.
- Build your library with
rollup-plugin-typescript2, which produces a single file with no imports, but no typing definition files.
- Build using webpack and
awesome-typescript-loader, with the right plugin configuration.
- And others
tschacks involving symlinks or post-build scripts
The TypeScript compiler supports an API much like Babel’s, which allows us to transform the code it outputs. Transformers can basically turn any code into any other valid code, so we use it to re-write easy-to-write but hard-to-compile absolute imports into relative imports that
ttypescript makes it easy to compile or run with transformer plugins!
It’s as easy as adding the plugin to your
tsconfig.json and running
tts-node as you’d usually run their native typescript equivalents.
We’ve been using it at ActivePipe (my excellent workplace) in production and are enjoying the advantage of absolute import paths when refactoring and breaking apart our larger modules while still maintaining flexibility of compiling to basically any project.
Contributions and bug reports welcome and hopefully this eases some pain the TypeScript community has been having writing modular and packaged code.