vercel / next.js

The React Framework
https://nextjs.org
MIT License
125.83k stars 26.85k forks source link

tsconfig > compilerOptions.paths > `${configDir}` template variable fails the app load and build #70912

Open alexilyaev opened 1 week ago

alexilyaev commented 1 week ago

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/next-tsconfig-configdir-l7jgmy?file=%2Ftsconfig.json%3A23%2C15

To Reproduce

  1. Fork the sandbox
  2. Run pnpm install
  3. Run pnpm dev
  4. The app fails to load due to import path alias issue

Current vs. Expected behavior

Current

TypeScript has added the ${configDir} Template Variable for Configuration Files in TypeScript 5.5. This template variable is essential for creating extendable configs, e.g.: https://github.com/alexilyaev/configs/blob/main/tsconfig/next.json

But it doesn't work in Next.js when used in tsconfig.json > compilerOptions.paths values.

We can verify that the config works because navigating imports that use the path aliases works as expected. Also running pnpm tsc --noEmit doesn't fail (pnpm prefix to run the project TypeScript version and not the global one).

Expected

Using ${configDir} Template Variable in tsconfig.json should not fail the Next.js app load and build.

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP PREEMPT_DYNAMIC Sun Aug  6 20:05:33 UTC 2023
  Available memory (MB): 4102
  Available CPU cores: 2
Binaries:
  Node: 20.9.0
  npm: 9.8.1
  Yarn: 1.22.19
  pnpm: 8.10.2
Relevant Packages:
  next: 15.0.0-canary.179 // Latest available version is detected (15.0.0-canary.179).
  eslint-config-next: N/A
  react: 19.0.0-rc-2d16326d-20240930
  react-dom: 19.0.0-rc-2d16326d-20240930
  typescript: 5.6.2
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Developer Experience, Module Resolution, TypeScript

Which stage(s) are affected? (Select all that apply)

next dev (local), next build (local)

Additional context

I've encountered this issue when I tried to move my tsconfig.json settings to an external repo and use it in my repo via extends in tsconfig.json. On the TypeScript side, everything worked. But Next.js failed to build.

alexilyaev commented 1 week ago

Please note there's also an issue with using ${configDir} in the include array in the extendable config.

// e.g. tsconfig.json
{
  "extends": ["@alexilyaev/configs/tsconfig/next"]
}

In Next v14.2.14:

> next dev --turbo

  ▲ Next.js 14.2.13 (turbo)
  - Local:        http://localhost:3000
  - Environments: .env.local

 ✓ Starting...
TypeError: Cannot read properties of undefined (reading 'push')
    at writeConfigurationDefaults (/Users/alex/www/Node/Personal/portfolio-manager/node_modules/.pnpm/next@14.2.13_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/lib/typescript/writeConfigurationDefaults.js:236:30)
    at async verifyTypeScriptSetup (/Users/alex/www/Node/Personal/portfolio-manager/node_modules/.pnpm/next@14.2.13_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/lib/verify-typescript-setup.js:121:9)
    at async verifyTypeScript (/Users/alex/www/Node/Personal/portfolio-manager/node_modules/.pnpm/next@14.2.13_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.js:112:26)
    at async startWatcher (/Users/alex/www/Node/Personal/portfolio-manager/node_modules/.pnpm/next@14.2.13_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.js:139:29)
    at async setupDevBundler (/Users/alex/www/Node/Personal/portfolio-manager/node_modules/.pnpm/next@14.2.13_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/router-utils/setup-dev-bundler.js:775:20)
    at async Span.traceAsyncFn (/Users/alex/www/Node/Personal/portfolio-manager/node_modules/.pnpm/next@14.2.13_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/trace/trace.js:154:20)
    at async initialize (/Users/alex/www/Node/Personal/portfolio-manager/node_modules/.pnpm/next@14.2.13_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/router-server.js:79:30)
    at async Server.<anonymous> (/Users/alex/www/Node/Personal/portfolio-manager/node_modules/.pnpm/next@14.2.13_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/next/dist/server/lib/start-server.js:249:36)

In Next v15.0.0-canary.179:

It doesn't throw, but it does duplicate the include array into tsconfig.json and add .next/types to it even though it's already defined...

// tsconfig.json after running `next dev --turbo`
{
  "extends": ["@alexilyaev/configs/tsconfig/next"],
  "include": [
    "${configDir}/**/*.ts",
    "${configDir}/**/*.mts",
    "${configDir}/**/*.tsx",
    "${configDir}/**/*.json",
    "${configDir}/src/env.js",
    "${configDir}/next-env.d.ts",
    "${configDir}/.next/types/**/*.ts",
    ".next/types/**/*.ts"
  ]
}