vercel / next.js

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

transpilePackages Not Working Properly with Yarn Workspaces (Monorepo) #62468

Closed brianlenz closed 9 months ago

brianlenz commented 9 months ago

Link to the code that reproduces this issue

https://github.com/throughtheword/next-workspace-test

To Reproduce

After cloning repository:

  1. yarn install
  2. cd web-common
  3. yarn build or yarn dev

If, before step 3, you run yarn tscompile (which just does a tsc -b in web-common), that will fail due to next-env.d.ts not being present, so it can't resolve the CSS module import in the SharedComponent.tsx:

src/components/SharedComponent.tsx:2:21 - error TS2307: Cannot find module './SharedComponent.module.css' or its corresponding type declarations.

2 import classes from './SharedComponent.module.css';
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Found 1 error.

If you run yarn tscompile after yarn build, then it will work since the next-env.d.ts file exists. If you run yarn build after yarn tscompile, then it will also work since tsc will build the referenced common dependency.

This is somewhat similar to this discussion: https://github.com/vercel/next.js/discussions/47010 It's a bit of a chicken-and-egg problem: does tsc come first or next build? Both fail when run first.

The key, however, is that for some reason, Next.js doesn't honor transpilePackages. So, even if next-env.d.ts always exists (to work around the yarn tscompile chicken-and-egg problem), when doing yarn dev, hot reloading of files in the common package are not picked up (unsurprisingly since Next.js seems to know nothing about that package for some reason). The reference and transpilePackages must work to provide the optimal developer experience.

Note that it doesn't make a difference whether you use nodeLinker: node_modules in .yarnrc.yml or if you remove it and use Yarn Plug'n'Play; the same issue occurs either way.

Current vs. Expected behavior

Current Behavior

Build errors out during type checking due to @test/common package not being transpiled, even though configured through transpilePackages in next.config.js:

   ▲ Next.js 14.1.0

   Linting and checking validity of types  ..Failed to compile.

./src/components/SharedComponent.tsx:1:32
Type error: Cannot find module '@test/common' or its corresponding type declarations.

> 1 | import { doAmazingStuff } from '@test/common';
    |                                ^
  2 | import classes from './SharedComponent.module.css';
  3 |
  4 | export const SharedComponent = () => {

Expected Behavior

@test/common package located in the common directory should be transpiled before the Next.js build so that the @test/common package can be found.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:44 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6000
  Available memory (MB): 65536
  Available CPU cores: 10
Binaries:
  Node: 18.19.0
  npm: 10.2.3
  Yarn: 4.1.0
  pnpm: N/A
Relevant Packages:
  next: 14.1.1-canary.71 // Latest available version is detected (14.1.1-canary.71).
  eslint-config-next: 14.1.1-canary.71
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.3.3
Next.js Config:
  output: N/A

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

TypeScript (plugin, built-in types)

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

next dev (local), next build (local)

Additional context

I've been trying to fix/workaround this issue for many hours. I've done a lot of research and haven't found any similarly reported issues in GitHub. I don't know if there's something I'm doing wrong or what, but it seems like a pretty simple example that should work. I originally discovered the issue when building a new app with 14.1.0. I tried reverting to 13.1.0 when Module Transpilation was first introduced, and it has the same issue. I've confirmed the issue still exists with the latest canary build.

It's also worth noting that even if you enable eslint.ignoreDuringBuilds and typescript.ignoreBuildErrors (to skip the initial lint and type checking), the build will still fail:

▲ Next.js 14.1.1-canary.71

   Skipping validation of types
   Skipping linting
   Creating an optimized production build ...
Failed to compile.

./src/components/SharedComponent.tsx
Module not found: Can't resolve '@test/common'

https://nextjs.org/docs/messages/module-not-found

Import trace for requested module:
./src/pages/index.tsx

> Build failed because of webpack errors

FWIW, I've also tested with next-transpile-modules, and it seems to have the same issue? Is there something about this simple setup that isn't supported? 🤯

brianlenz commented 9 months ago

I figured out the issue. It was a misconfiguration. The key was to not use references in tsconfig.json when using Next.js and instead use compilerOptions.paths to map them. Then, it seems transpilePackages works, along with hot reloading.

github-actions[bot] commented 8 months ago

This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.