nx icon indicating copy to clipboard operation
nx copied to clipboard

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

Open TheMeteoRain opened this issue 4 years ago • 12 comments

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

TheMeteoRain avatar Sep 24 '21 08:09 TheMeteoRain

You will need tsconfig-paths for executing built file with path mapping configurated.

linbudu599 avatar Sep 24 '21 10:09 linbudu599

I thought there might be something wonky with the underlying implementation in the @nrwl:node. If it's not that, then it's kinda strange that the same principle is not same between libs.

I will try that and post back here what kind of hurdles I had to do. It's a familiar tool, so I don't expect anything too difficult.

TheMeteoRain avatar Sep 25 '21 01:09 TheMeteoRain

@linbudu599 There is no way to modify webpack or rollup config (whichever @nrwl/node:package uses). So basically there is no way of using tsconfig-paths. At least not in a way I know of.

I can switch to @nrwl/node:build where I can modify webpack config, but the output is single file. I bet it's used for express etc. applications. @nrwl/node:build understood tsconfig paths without any extra hassle just like @nrwl/web:package (react lib uses this).

I want to keep the file structure, which @nrwl/node:package did kept. Shouldn't @nrwl/node:package understand tsconfig paths out of the box? Or at least expose the config.

TheMeteoRain avatar Sep 26 '21 18:09 TheMeteoRain

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.

linbudu599 avatar Sep 27 '21 07:09 linbudu599

Thank you for some clarifications. And yes my problem is that the compiled output in the dist folder still has wrong paths.

I actually ditched all @nrwl executors since non of them match my needs. I ended up with result where all the path aliases resolved correctly and the folder structure was kept intact. I do not want to compile all my code to single file. It actually harms my use case a lot when importing said library.

I can post my codes later this week. They might help you with the plugin or with some help I can write the plugin. But let's see once you see the code.

TheMeteoRain avatar Sep 27 '21 12:09 TheMeteoRain

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.

vugar005 avatar Feb 03 '22 14:02 vugar005

@TheMeteoRain I'm not sure how helpful this is, but I had a similar problem with nx not picking up path aliases. What I did notice was that if I imported from index it resolved just fine (one because only the other imports gave an error, and because I tried testing on a fresh git tree and I noticed the same pattern ). Hence, I tried reexporting the default exports I was referencing from the root src folder in the index file and it works. It's a workaround, but that's the only export that is being recognised right now, Once the repo is public, I'll update this comment in case I figure out why it has this strange behaviour later on.

islami00 avatar Feb 20 '22 16:02 islami00

Any updates here? Having the same issue when using lib in express js app. If I change the name of the path it works randomly.

simonbergstrom avatar Apr 11 '22 12:04 simonbergstrom

UPDATE: Changing path works if node_modules is already installed. If I delete node_modules after change path name the same error as described in this issue is back again.

simonbergstrom avatar Apr 11 '22 13:04 simonbergstrom

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.

mmaterowski avatar Apr 28 '22 08:04 mmaterowski

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.

roddc avatar Jul 06 '22 05:07 roddc

May be helpful: tsconfig paths in rollup don't work for JS file.

To solve, just convert your JS files to TS/TSX

michelepatrassi avatar Aug 09 '22 13:08 michelepatrassi

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

melalj avatar Aug 16 '22 23:08 melalj

I'm having similar issue, but it's on @nrwl/webpack:webpack

Here is my paths alias in tsconfig.base.json:

"paths": {
      "@bf/auth": ["libs/bf-auth/src/index.ts"],
      "@bf/database": ["libs/bf-database/src/index.ts"],
      "@myorg/core/api": ["libs/core/core-api/src/index.ts"]
}

After build, the "@bf/auth" and "@bf/database" always recognized as external packages. Customizing webpack config using tsconfig-paths-webpack-plugin did not work for me either.

Then tried to make all aliases with a same prefix (my root package.json name is "@myorg") like these:

"paths": {
      "@myorg/auth": ["libs/bf-auth/src/index.ts"],
      "@myorg/database": ["libs/bf-database/src/index.ts"],
      "@myorg/core/api": ["libs/core/core-api/src/index.ts"]
 }

surprisingly it's working!

So I tried another workaround my workaround by put slash right after @ sign like this:

"paths": {
      "@/bf/auth": ["libs/bf-auth/src/index.ts"],
      "@/bf/database": ["libs/bf-database/src/index.ts"],
      "@myorg/core/api": ["libs/core/core-api/src/index.ts"]
}

and it's working too!

But still I think this is not a good solution -- just in case one day I want to publish @bf/auth and @bf/database on npm, I should only need to rid of the paths from tsconfig and add those packages to my projects.

budiadiono avatar Dec 18 '22 15:12 budiadiono

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"
          }
        ]
      }
    },
...

lafbelmonte avatar Feb 17 '23 01:02 lafbelmonte

Thanks @lafbelmonte, This solution works.

quicksilverr avatar Apr 27 '23 07:04 quicksilverr

Hello all! Thank you for digging into this issue and coming up with solutions! I will be closing this issue now for two reasons:

  1. It seems that there are working workarounds
  2. The initial report is outdated, and lots has changed since then.

I hope that these comments help whoever may come up with something similar, but if you do find an issue that you think is not yet covered by Nx natively, please open a new issue on Nx, and tag me, and I will look into it!

Again, THANK you everyone!!

mandarini avatar Oct 24 '23 12:10 mandarini

This issue has been closed for more than 30 days. If this issue is still occuring, please open a new issue with more recent context.

github-actions[bot] avatar Nov 24 '23 00:11 github-actions[bot]