NextJS can't resolve module in external workspace package

Viewed 441

Error module not found. pnpm-workspace.

My problem

I get a "module not found" error in my nextjs project when running dev.

I get this error when I use a path alias defined in a tsconfig inside a package. Relative imports do work. It's like the loader doesn't see my compilerOptions.path setting inside the package-scoped tsconfig.

I'm using pnpm workspaces. But I'm 99% sure the same error would occur when using yarn.

Thanks in advance.

The error

error - ../database/config/models.ts:1:0
Module not found: Can't resolve '@models/business/Business.model'
> 1 | import Business from "@models/business/Business.model"
  2 | import Image from "@models/Image.model"
  3 | import Site from "@models/Site.model"
  4 | import User from "@models/user/User.model"

If you think I missed something. You can find more info in this screenshot

My file structure

  • tsconfig.base.json
  • backend/
  • database/
  • shared/
  • web/ (this is the nextjs app)
    • next.config.js
    • tsconfig.json
    • pages/
    • ...

Every package has a tsconfig.base.json that extends tsconfig.base.json

My config files

tsconfig.base.json

{
    "compilerOptions": {
        "target": "ES2017",
        "module": "ESNext",
        "lib": ["esnext", "ESNext.AsyncIterable"],
        "allowJs": false,
        "skipLibCheck": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "noEmit": false,
        "esModuleInterop": true,
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "jsx": "preserve",
        "incremental": true,
        "experimentalDecorators": true,
        "strictPropertyInitialization": false,
        "emitDecoratorMetadata": true,
        "baseUrl": ".",
        "paths": {}
    },
    "include": [""],
    "exclude": ["node_modules", "_*"]
}

web/tsconfig.json

{
    "extends": "../tsconfig.base.json",
    "compilerOptions": {
        "lib": ["dom", "dom.iterable", "esnext"],
        "allowJs": true,
        "skipLibCheck": true,
        "strict": false,
        "forceConsistentCasingInFileNames": true,
        "noEmit": false,
        "incremental": true,
        "esModuleInterop": true,
        "module": "esnext",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "jsx": "preserve",
        "baseUrl": "."
    },
    "include": ["next-env.d.ts", "./**/*.ts", "./**/*.tsx"],
    "exclude": ["node_modules"]
}

database/tsconfig.json

{
    "extends": "../tsconfig.base.json",
    "compilerOptions": {
        "baseUrl": ".",
        "rootDir": ".",
        "paths": {
            "@resolvers/*": ["./resolvers/*"],
            "@models/*": ["./models/*"],
            "@config/*": ["./config/*"]
        }
    },
    "include": ["./**/*.ts"]
}

next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
    experimental: {
        externalDir: true,
    },
    reactStrictMode: true,
    webpack: (config, { isServer }) => {
        config.resolve.fallback = { fs: false }

        // Fixes api routes crashing
        config.experiments = {
            topLevelAwait: true,
            // it makes a WebAssembly modules async modules
            syncWebAssembly: true,
            asyncWebAssembly: true,
            layers: true,
        }

        // generate wasm module in ".next/server" for ssr & ssg
        if (isServer) {
            config.output.webassemblyModuleFilename = "./../static/wasm/[modulehash].wasm"
        } else {
            config.output.webassemblyModuleFilename = "static/wasm/[modulehash].wasm"
        }

        return {
            ...config,
        }
    },
}

module.exports = nextConfig
0 Answers
Related