DEV Community

Discussion on: Node.js with TypeScript, Debug inside VSCode and Nodemon

Collapse
 
dtx92 profile image
DTX-92

Awesome, thanks
But can you please explain, how do I add support for module aliases?

Collapse
 
oieduardorabelo profile image
Eduardo Rabelo • Edited

thanks for your comment,

absolutely, for this setup it would be a little bit tricky, because:

  • we are not using a bundler (e.g. webpack, rollup etc)
  • if you use a module alias, the output Node.js code (e.g. inside "dist/*.js"), will have the aliased path, since TypeScript does not replace the import path string
  • because of that, you will need to maintain some kind of module alias resolution in the prod version for Node.js only (e.g. you need to start your server with a module alias solution)
  • we also need to keep mappings for Jest, because Jest doesn't use TypeScript module resolution

let's put the production scenario above aside, and focus on "dev" only, we can do:

let's clone the repo:

git clone https://github.com/oieduardorabelo/node-typescript
cd node-typescript
npm install
Enter fullscreen mode Exit fullscreen mode

and install tsconfig-paths

npm install tsconfig-paths
Enter fullscreen mode Exit fullscreen mode

inside our tsconfig.json we can define baseUrl and paths:

{
  "compilerOptions": {
     ...
    "baseUrl": ".",
    "paths": {
      "#domains/*": ["src/domains/*"]
    }
  },
  ...
}
Enter fullscreen mode Exit fullscreen mode

now we can use the alias #domains in any file, let's update server.ts:

...
import bookRoutes from '#domains/book/routes';
import reviewRoutes from '#domains/review/routes';

const server = express();
...
Enter fullscreen mode Exit fullscreen mode

now, let's register the module alias in our nodemon.json:

{
  ...
  "execMap": {
    "ts": "node --require ts-node/register --require tsconfig-paths/register"
  },
  ...
}
Enter fullscreen mode Exit fullscreen mode

now we can start the server with aliases:

npm run dev
Enter fullscreen mode Exit fullscreen mode

and it should work as before, but with aliases!

now, for the Jest mappings, you need to keep the same mappings from tsconfig.json but in the Jest syntax/config, we need to use moduleNameMapper. I'll add the Jest config in package.json for this example:

{
  ...
    "moduleNameMapper": {
      "^#domains/(.*)": "<rootDir>/src/domains/$1"
    }
  ...
}
Enter fullscreen mode Exit fullscreen mode

and now you can run your tests as before:

npm run test
Enter fullscreen mode Exit fullscreen mode

so far, so good.

now, for the production scenario, I do not have a good straight answer, because it requires a considerable amount of work to adapt it per project.

but thinking about the process to make it work, we could use something like module-alias

and we would need:

  • build the project with npm run build (e.g. typescript => node.js in dist/)
  • have a script to generate a package.json with module-alias inside dist/
  • add the same mappings from tsconfig.json inside dist/package.json but using module-alias syntax
  • run cd dist/ && npm install to install module-alias for production
  • and start your production server with node --require module-alias/register entry.js

phew, what a setup! ahahah

i hope it helped! 👋