nx: @nrwl/node:lib won't resolve tsconfig path aliases

Current Behavior

I am using path aliases in tsconfig.json in my generated @nrwl/node:lib.

Let’s say tsconfig.json paths looks like this "paths": { "@test": ["src/lib/index.ts"], }

And let’s say I use it like this in the code import something from '@test'

Expected Behavior

When I build my library the code should look something like this import something from '../../i/am/relative/path/to/the/right/place'

Instead it still looks like this import something from '@test'

Steps to Reproduce

nx g @nrwl/node:lib name --buildable Add path alias to tsconfig.json nx build name

Compare imports from the source files and the dist.

Site note

This same configuration works for @nrwl/react:lib but not for this @nrwl/node:lib

Environment

$ nx report

>  NX  Report complete - copy this into the issue template

  Node : 16.8.0
  OS   : darwin x64
  yarn : 1.22.10
  
  nx : 12.9.0
  @nrwl/angular : Not Found
  @nrwl/cli : 12.9.0
  @nrwl/cypress : 12.9.0
  @nrwl/devkit : 12.9.0
  @nrwl/eslint-plugin-nx : 12.9.0
  @nrwl/express : Not Found
  @nrwl/jest : 12.9.0
  @nrwl/linter : 12.9.0
  @nrwl/nest : Not Found
  @nrwl/next : Not Found
  @nrwl/node : 12.9.0
  @nrwl/nx-cloud : Not Found
  @nrwl/react : 12.9.0
  @nrwl/schematics : Not Found
  @nrwl/tao : 12.9.0
  @nrwl/web : 12.9.0
  @nrwl/workspace : 12.9.0
  @nrwl/storybook : 12.9.0
  @nrwl/gatsby : Not Found
  typescript : 4.3.5

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 13
  • Comments: 18 (3 by maintainers)

Most upvoted comments

Sorry, my explanation is not very detailed, let me carefully list the questions in the above conversation:

  • @nrwl/node:build uses Webpack under the hood(as well as @nrwl/web:build), so it does understand path alias and replace @test/test.ts with ./relative/path/test.ts.
  • @nrwl/node:package uses TypeScript compiler directly, so it’s not changing path alias(but it will include aliased path to build)
  • Why I’m saying You will need tsconfig-paths for executing built file with path mapping configurated. is that I thought you wants to execute built file but facing the cannot find module @tests/test error.
  • If you just want alias path to be replaced correctly in compiled file, you will need to handle it yourself for now, as tsconfig-paths works at run-time intead of compile-time, it cannot solve your problem either.
  • I’ve searched for and found something may fits you well: tscpaths, which works at compile-time and will change your alias path.
  • To intergate this tool with your workflow, I’d like to suggest that it your target lib has no workspace package dependencies, it’s ok to use @nrwl/workspace:run-commands and commands like ['tsc --options', 'tscpaths --options']. Otherwise it’s getting more complicated, you need to copy source code of @nrwl/node:package executor and add your own codes…, but I will do this thing soon in nx-plugin-workspace.

My problem was transitioning from existing angular CLI project to nx. During that process nx renames:

tsconfig.json to -> tsconfig.base.json

and that’s what vscode didn’t handle very well. Even after restarting TS server, changing paths, adjusting baseUrl, deep-diving into extending process, etc…

After investigating multiple approaches it turns out that while running tsc --traceResolution all modules and imports were resolved as expected. I renamed tsconfig.base.json to tsconfig.json and everything was working again @vsavkin is it a known issue?

@vugar005 configuration is the right one, what’s maybe worth mentioning is that in tsconfig.json I set baseUrl to “.”

{
...
"baseUrl": "."
}

Works without any extra mapping configurations or packages. Also with es-lint.

Make sure you pass correct full path. // tsconfig.json in apps/mfe1 folder

  "compilerOptions": {
   ....
    "paths": {
      "@core/*": ["apps/mfe1/src/app/core/*"]
    }
  },

Also,I discovered that thanks to comment. That even if your local tsconfig.json path is empty , it would just override tsconfig.base.json. // tsonfig.json in apps/mfe1 folder

  "paths": {
     // if you specify any paths they will be removed, if you have paths in tsconfig.json
    }

So this is very important and I hope NX resolves it soon.

If you’re using nrwl/js:tsc, you can use typescript-transform-paths and pass it in transformers parameter. E.g. project.json

...
  "targets": {
    "build": {
      "executor": "@nrwl/js:tsc",
      "outputs": ["{options.outputPath}"],
      "options": {
        "outputPath": "dist/apps/e-api",
        "main": "apps/e-api/src/index.ts",
        "tsConfig": "apps/e-api/tsconfig.lib.json",
        "assets": ["apps/e-api/*.md"],
        "transformers": [
          { 
            "name": "typescript-transform-paths/nx-transformer"
          }
        ]
      }
    },
...

I’m facing a similar issue with my current setup:

apps
  | - my-app
libs
  | - common
  | - my-client

The libs are being published on npm after the deployment under the names of @my-org/my-client and @my-org/common, while I’m defining the following path alias (on tsconfig.conf) to use them directly on my-app code:

"paths": {
      "@my-org/my-client": ["libs/my-client/src/index.ts"],
      "@my-org/common": ["libs/common/src/index.ts"]
}

The issue is that my-app is using an external package another-external-package that depends on @my-org/common (it’s importing with its published version).

When I import @my-org/common on my-app, it seems that it’s picking up the peer dependency @my-org/common (from another-external-package) and not from the alias that is defined on tsconfig.conf. This happens only when we build for production but not in the dev environment.

Any idea on how to tell nx/tsc to pick the library instead of the published package?

@linbudu599 @TheMeteoRain

I try to overwrite the paths in my-lib/tsconfig.json :

"paths": { "@/*":["libs/my-lib/src/*"]}

but I got an error Cannot resolve module @/lib/test/index.tsx from compiler I don’t want to import modules from relative path e.g. ../../../test. How do I overwrite the path alias in lib folder. However, if I add above to tsconfg.base.json, it works.