How to change the ts path aliases for an nx application
Asked Answered
P

4

8

I am importing an existing application into an NX monorepo with a file structure a little different from default apps. It looks like this:

apps
  my-app
    src
      feature-1
      feature-2
      main
        components
          my-component.tsx
        index.tsx
    tsconfig.json

Due to this layout of everything being inside src/main, I want all my absolute imports to start from src/main.

// src/main/index.tsx
import MyComponent from 'components/my-component'

Which should resolve to src/main/components/my-component. Obviously I could absolute import this specific example, but the actual one is a huge application and this isnt a feasible solution.

In this original single app repository, we achieved this by setting paths inside tsconfig

// tsconfig.json
{
  "compilerOptions": {
     ...     
     "paths": {
       "*": ["src/main/*", "node_modules/*"]
     }
  }
}

However, as NX's root tsconfig uses paths to map to libraries, this is no longer a valid solution. How can I tell NX to resolve my imports from src/main instead of src?

I have tried setting resolve.modules to path.resolve(__dirname, 'src/main') in my webpack config, but it didn't seem to work. I have also tried setting baseUrl in the app's tsconfig but that then removes my ability to import libraries.

Pacific answered 21/1, 2022 at 20:5 Comment(0)
H
13

Nx should have created a tsconfig.base.json file in your workspace root where all the paths declarations for libs go.

Option 1

I think the "Nx" preferred way to make one or more libs out of your app code. In other words, move your src/main directory out of apps/my-app/ and into libs/main/ or libs/my-app/main/. The Nx team has suggested that 99% of code should live in libraries, even if it's application-specific. That way you can test it independently of the application.

Option 2

However, if you don't want to take the time to divide your code up into libs, you might be able to take a shortcut, by specifying:

// tsconfig.base.json
{
  "compilerOptions": {
     ...     
     "paths": {
       "main/*": ["apps/my-app/src/main/*"]
     }
  }
}

You would have to prepend main/ to all your imports, but that should be fairly easy with a find-and-replace.

Option 3 (speculation, untested)

You might be able to use the same technique as before, but specify the path from the root of your workspace:

// tsconfig.base.json
{
  "compilerOptions": {
     ...     
     "paths": {
       "*": ["apps/my-app/src/main/*"]
     }
  }
}

Option 4 (speculation, untested)

You might be able to override the paths in tsconfig.base.json file with the the tsconfig.json file in your app directory:

// tsconfig.json
{
  "compilerOptions": {
     ...     
     "paths": {
       "*": ["src/main/*", "node_modules/*"]
     }
  }
}

This one may or may not lead to losing the ability to import other libs. I suppose that depends on how the tsconfig files get merged.

Hulton answered 25/1, 2022 at 21:36 Comment(2)
4 does indeed seem to break importing other libsPhenice
Using the tsconfig.base.json naming schemed didn't work in vscode with angular. @ngGirl's suggestion of fixing the name seems to make the paths work. https://mcmap.net/q/1262246/-how-to-change-the-ts-path-aliases-for-an-nx-applicationUranous
D
3

baseUrl is the problem!

I ended up here having a similar problem after migrating my Angular app to NX and tried to create libraries.

In my case the problem was actually that the libraries were taking as base path the one from the app (in apps/my-app) instead of the root folder of the project.

So I had to do something ugly in the paths such as:

paths: [
  "@keira/acore-world-model": ["../../../libs/acore-world-model/src/index.ts"]

To fix this, make sure that there is no baseUrl property overriding the settings in each app or lib (in my case I deleted all occurrences of baseUrl inside any tsconfig.json file of the libraries or apps and I could get rid of the ugly ../../../ part.

Only the root tsconfig.conf file shall have a baseUrl and it has to be set to "."

Desexualize answered 2/3 at 9:46 Comment(0)
D
2

I faced the same issue trying to migrate an Angular 14 app to Nx. Absolute paths (for app and libs) were fixed by renaming nx-generated tsconfig.base.json to tsconfig.json and updating any paths.

Devote answered 29/4, 2023 at 9:26 Comment(4)
This appears to be the actual solution for me working in vsCode with Angular. It's like something is configured to only look for tsconfig.json, and won't work with tsconfig.base.json. I searched and couldn't find it. I will note that any paths added to the subordinate configs will not work. I tried sticking a path in the tsconfig.app.json which I updated to extend the tsconfig.json file. It was not recognized like the original problem.Uranous
I got further along in my conversion, and realized the issue was that @nx/eslint-plugin needed to be installed. Once that was in place I was able to leave the tsconfig.base.json as it was.Uranous
Ran into issues again after restarting vscode. I had to add a tsconfig.json file in the same folder as the tsconfig.base.js. I set this to do nothing but extend tsconfig.base.json. This made both NX and typescript happy. It feels quirky, but it has worked around the problem.Uranous
worked for me, but am not sure why did not NX fix it from their side. My project was started from scratch using their generatorsTertius
P
0

I'm coming back to this a year later with a bit more nx experience. I didn't find my answer via tsconfig, but I did with nx generators. I simply extended the nx react library generator by modifying the tsconfigs of all apps in the project to match the base one, so the generator did the job of manually adding the paths to all of my existing tsconfigs.

Not perfect, but it works.

Pacific answered 7/7, 2023 at 19:9 Comment(1)
Do you have an example about this? I am facing a similar issueBlinni

© 2022 - 2024 — McMap. All rights reserved.