3

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.

plusheen
  • 1,128
  • 1
  • 8
  • 23

3 Answers3

9

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.

chris
  • 2,893
  • 3
  • 20
  • 22
0

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.

ngGirl
  • 1
  • 1
  • 2
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.

plusheen
  • 1,128
  • 1
  • 8
  • 23