Search code examples
reactjstypescriptwebpacknext.jsbabel-loader

Module's not resolving in typescript monorepo with Next.js projects


I have a monorepo using yarn workspaces that has 2 Next.js projects.

apps
 ┣ app-1
 ┗ app-2

app-1 needs to import components from app-2. To do this, I add the app-2 project as a dependency and set the path in our app-1 tsconfig like so:

app-1 package.json
{
  "name": "@apps/app-1",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@apps/app-2": "workspace:*",
  }
}
app-1 tsconfig.json

{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "@apps/app-2/*": ["../../app-2/src/*"],
      "@apps/app-2": ["../../app-2/src"]
    }
  }
}

This works just fine, however, the problem happens when a component in app-2 imports other components like import Component from "components/Component".

app-1 doesn't know how to resolve it and is looking for components/Components inside it's own src folder which does not exist. If that same component imported like this import Component from ../../Component it would resolve properly. To fix this, I set another path inside of app-1's tsconfig file to manually resolve. Now my tsconfig looks like

app-1 tsconfig
{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "components/*": ["../../app-2/src/components/*"], // new path resolves absolute urls from app-2
      "@apps/app-2/*": ["../../app-2/src/*"],
      "@apps/app-2": ["../../app-2/src"]
    }
  }
}

Without that line of text, trying to dev or build the app-1 project renders Type error: Cannot find module 'components/Component' or its corresponding type declarations. I don't want to manually resolve it this way because app-1 might want it's own components folder one day and would erroneously resolve to app-2's components folder.

It looks like a typescript issue based on the error, but I can't tell if maybe it has something to do with webpack/babel or from symlinks in our node_modules

The ideal solution is to change something with our config or loaders and have these path resolve as you'd expect.


Solution

  • I had tried the provided answers and unfortunately they didn't work for me. What did end up fixing it, after reading through some documentation, was a simple tsconfig change in app-1:

    {
      "compilerOptions": {
        "baseUrl": "./src",
        "paths": {
          "*": ["*", "../../app-2/src/*"], // try to resolve in the current baseUrl, if not use the fallback.
          "@apps/app-2/*": ["../../app-2/src/*"], // reference app-2 imports inside app-1 like "import X from '@apps/app-2/components'"
        }
      }
    }
    
    

    Note that since these are both Next.js projects sharing code with each other, I had to use next-transpile-modules and wrapped each next.config.js in the withTM function as outlined in their docs