vercel / next.js

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

Error: [...] requires a reflect polyfill. Please add 'import "reflect-metadata"' to the top of your entry point. #53870

Open wouterds opened 1 year ago

wouterds commented 1 year ago

Verify canary release

Provide environment information

Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 22.5.0: Thu Jun  8 22:21:34 PDT 2023; root:xnu-8796.121.3~7/RELEASE_ARM64_T8112
    Binaries:
      Node: 20.5.0
      npm: 9.8.0
      Yarn: 1.22.19
      pnpm: N/A
    Relevant Packages:
      next: 13.4.12
      eslint-config-next: 13.4.12
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.1.6
    Next.js Config:
      output: N/A

Which area(s) of Next.js are affected? (leave empty if unsure)

App Router

Describe the Bug

Any DI package depends on reflect-metadata. Previously, before App Router, you could import this in _app.tsx and all was well. This doesn't exist or work anymore with App Router and I have no clue where or how I could make it work. I tried importing it in the root layout, as well as pre-loading it using the package.json scripts but none of that works.

What is the best way to get reflect-metadata working with Next.js >= 13.4?

Expected Behavior

Being able to load reflect-metadata in a decent way without hacking.

Relevant links

patotoma commented 1 year ago

Based on discussion in here https://github.com/vercel/next.js/discussions/20992#discussioncomment-5829202

You should be able to import polyfills from your root layout and just set them as "use client"

I'm about to try this myself for some other polyfills too but noticed your issue so I thought about sharing.

ivan-kleshnin commented 1 year ago

You should be able to import polyfills from your root layout and just set them as "use client"

It works partially.

I used to export twMerge globally (because it's required in so many files). E.g. the following does not work in app-router anymore:

// globals.ts

"use client"
import * as TWM from "tailwind-merge"

declare global {
  var twMerge: typeof TWM.twMerge
}

const twMerge = TWM.extendTailwindMerge({
  ...
})

globalThis.twMerge = twMerge

global twMerge access is compiled properly in TS but fails at next build 🤷