Search code examples
node.jstypescriptnext.jstsconfignext.js13

"Cannot find module" errors despite correct paths provided in tsconfig


I'm running into this recurring issue in my project when it comes to building my next app.

My project structure is the following:

├── src
│   ├── app
│   │   ├── (buyer)
│   │   ├── (login)
│   │   ├── (vendor)
│   │   ├── api
│   │   ├── layout.tsx
│   │   ├── page.module.css
│   │   ├── page.tsx
│   │   └── providers.tsx
│   ├── constants
│   │   └── next-auth.ts
├── tailwind.config.js
├── tsconfig.json
└── tsconfig.spec.json

When building this app, I'm running into "cannot find module" errors, mostly complaining about paths not being resolved.

For example:

Failed to compile.
       
       ../project-name/src/app/(buyer)/user/page.tsx:4:25
       Type error: Cannot find module '@/constants/next-auth' or its corresponding type declarations.
       
         2 | import { getServerSession } from 'next-auth'
         3 | 
       > 4 | import { OPTIONS } from '@/constants/next-auth'
           |                         ^
         5 | import { Session } from 'next-auth/core/types'
         6 | 
         7 | const User = async () => {
       Error occurred while trying to run the npx next build 
       Error: Command failed: npx next build 

The compiler is complaining that there is no path pointing to this module. Let's check the tsconfig.json:

{
    "extends": "../../tsconfig.base.json",
    "compilerOptions": {
      "baseUrl": ".",
      "target": "es5",
      "lib": ["dom", "dom.iterable", "esnext"],
      "allowJs": true,
      "skipLibCheck": true,
      "strict": true,
      "forceConsistentCasingInFileNames": true,
      "noEmit": true,
      "esModuleInterop": true,
      "module": "esnext",
      "moduleResolution": "node",
      "resolveJsonModule": true,
      "isolatedModules": true,
      "jsx": "preserve",
      "allowSyntheticDefaultImports": true,
      "incremental": true,
      "types": ["jest", "node"],
      "plugins": [
        {
          "name": "next"
        }
      ],
      "paths": {
        "@/*": ["./src/*"],
        "@/app/*": ["./src/app/*"],
        "@/constants/*": ["./src/constants/*"],
        ...
      },
    },
    "include": [
      "next-env.d.ts",
      "**/*.ts",
      "**/*.tsx",
      ...
    ],
    "exclude": [
      "node_modules",
      "jest.config.ts",
      "src/**/*.{spec,test}.ts"
    ]
}

I know I'm missing something, I just don't know where.


Solution

  • You just need to provide one path here.

    instead of

            "@/*": ["./src/*"],
            "@/app/*": ["./src/app/*"],
            "@/constants/*": ["./src/constants/*"],
            ...
    

    just have

    "@/*": ["./src/*"]
    

    Also make sure that you have defined baseUrl properly.