nx
nx copied to clipboard
@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
You will need tsconfig-paths for executing built file with path mapping configurated.
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.
@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.
Sorry, my explanation is not very detailed, let me carefully list the questions in the above conversation:
@nrwl/node:builduses Webpack under the hood(as well as@nrwl/web:build), so it does understand path alias and replace@test/test.tswith./relative/path/test.ts.@nrwl/node:packageuses 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 thecannot find module @tests/testerror. - If you just want alias path to be replaced correctly in compiled file, you will need to handle it yourself for now, as
tsconfig-pathsworks 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-commandsand commands like['tsc --options', 'tscpaths --options']. Otherwise it's getting more complicated, you need to copy source code of@nrwl/node:packageexecutor and add your own codes..., but I will do this thing soon in nx-plugin-workspace.
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.
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.
@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.
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.
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.
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.
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.
May be helpful: tsconfig paths in rollup don't work for JS file.
To solve, just convert your JS files to TS/TSX
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'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.
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"
}
]
}
},
...
Thanks @lafbelmonte, This solution works.
Hello all! Thank you for digging into this issue and coming up with solutions! I will be closing this issue now for two reasons:
- It seems that there are working workarounds
- 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!!
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.