How to Use the tsconfig.json "paths" Option in Node.js
Tags: javascript, node, programming, softwaredevelopment
Published: 2024-01-19 21:32:31

When working on a Node.js project, managing module imports can become a cumbersome task. Thanks to TypeScript and its `tsconfig.json` configuration file, you can use the `paths` option to simplify the process of importing modules. This feature allows you to define custom aliases, making the `import` or `require` instructions much more readable. At the same time, Node.js does not support that feature out of the box.

In this tutorial, you will learn how to use `tsconfig.json`‘s `paths` option in Node.js through the `tsconfig-paths` package. Time to make module management more efficient and maintainable!

## Why ts-node Does Not Support Paths

Suppose your `tsconfig.json` file contains the following code:

```json
{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "lib": ["es6"],
    "strict": true,
    "esModuleInterop": true,
    "outDir": "./build",
    "sourceMap": true,
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules", "**/*.spec.ts"]
}
```

Note the [`paths`](https://www.typescriptlang.org/tsconfig#paths) option, which allows you to specify a set of aliases that re-map imports to lookup locations. This makes the `require/import` instructions in your code easier to read, as below:

```javascript
import * as Constants from "@/constants"
import express from "express"

const app = express()

app.get("/hello-world", (req, res) => {
    res.json(Constants.HELLO_WORLD_MESSAGE)
})
```

Note how elegant the first `import` instruction is compared to something like this:

```javascript
import * as Constants from "./../../constants"
```

`paths` are cool, but unfortunately Node.js does not support them. Let's understand why!

In TypeScript, modules are resolved similarly to the way Node.js does. However, the `paths` option allows you to specify arbitrary module paths that don't start with `/` or `.`. These special aliases can be mapped to physical paths on the file system, which the TypeScript compiler can resolve from the `tsconfig.json` file. So, TypeScript will be able to compile the code successfully.

However, when trying to run files compiled `ts-node`, they will only look for modules in the `node_modules` folders up to the root of the file system. As a result, modules specified by `paths` in `tsconfig.json` will not be found and the Node.js server will fail with the following error:

```
Error: Cannot find module '@/contants'
```

Luckily, there is a solution and it is called `tsconfig-paths`. Time to learn how to configure it to make `paths` works in `ts-node`!

## Using paths in ts-node With tsconfig-paths

[`tsconfig-paths`](https://www.npmjs.com/package/tsconfig-paths) is an npm library that allows `ts-node` to load modules imported using the aliases defined in the `paths` section of `tsconfig.json`.

Add it to your project's dependencies with:

```shell
npm i tsconfig-paths
```

Then, update the command to launch your `ts-node`project as follows:

```shell
ts-node -r tsconfig-paths/register index.ts
```

Where `index.js` is your Node.js main TypeScript file.

Et voilà! The "Cannot find module" error is now gone and your `ts-node` project is working with `paths` aliases.

At the same time, if try to compile your TypeScript code with `tsc` and then launch it with `node`, you will still get a "Cannot find module" error. `tsconfig-paths` works like a charm with `ts-node` but still have some issues with `node`.

As you can read on the [official GitHub page of the issue](https://github.com/dividab/tsconfig-paths/issues/61), there are several workarounds to address the problem. An effective solution is to change the Node.js start command of the `tsc` compiled code to:

```shell
node -r ts-node/register/transpile-only -r tsconfig-paths/register build/index.js
```

Where `build/index.js` is the path to the main Node.js file in your `outDir` folder.

If you are worried about [using](https://github.com/TypeStrong/ts-node/issues/104#issuecomment-250252708) [`ts-node`](https://github.com/TypeStrong/ts-node/issues/104#issuecomment-250252708)[in production](https://github.com/TypeStrong/ts-node/issues/104#issuecomment-250252708), note that `ts-node/register/transpile-only` does not introduce significant performance overhead.

Congrats! Error fixed!

## Conclusion

In this article, you saw what `paths` are, how to configure them in `tsconfig.json`, why Node.js does not support them, and how to address this issue. Specifically, you learned that the `tsconfig-paths` library can help you make Node.js work with imports involving aliases defined in `paths`.

Thanks for reading! I hope you found this article helpful.
  
***
_The post "[How to Use the tsconfig.json "paths" Option in Node.js](https://writech.run/blog/how-to-use-the-tsconfig-json-paths-option-in-node-js-24ccb94b4506/)" appeared first on [Writech](https://writech.run)._