hoangvvo / next-connect

The TypeScript-ready, minimal router and middleware layer for Next.js, Micro, Vercel, or Node.js http/http2
https://www.npmjs.com/package/next-connect
MIT License
1.62k stars 65 forks source link

Yarn berry PnP + Next.js 12 has import error. #163

Closed minkichoe closed 2 years ago

minkichoe commented 2 years ago

error - Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'next-connect' imported from /app/.next/server/pages/api/test_endpoint.js

MatsG23 commented 2 years ago

The ESM support for PnP in yarn is still experimental. Meanwhile, you can set nodeLinker to node-modules in the yarn config file.

Sources: https://github.com/yarnpkg/berry/issues/638 https://nodejs.org/api/esm.html#esm_loaders

hoangvvo commented 2 years ago

I'm not familiar with Yarn PNP. Does a library author have to config their library is a specific way to work with Yarn PnP? My assumption was that it should just work.

MatsG23 commented 2 years ago

On the top of the issue I sent, the user says: In case you reach this thread by Twitter, ESM for PnP is on our roadmap. It's tricky due to some primitives currently missing in Node (they're working on this, but as you can see it's still branded as experimental), in the meantime if you need it then the node-modules linker remain a perfectly fine solution. Nonetheless the issue was opened in December 2019 and it will take more time, I assume.

I often use TS to "compile down" to CommonJS. What happens if you set compilerOptions.module from ESNext to CommonJS in your tsconfig.json?

dtothefp commented 2 years ago

I just ran into this issue as well when enabling SWC compiler when using Yarn Berry PNP. Can't quite tell from the yarn GH issue if this is resolved or not 🤷

It looks like the release for yarn berry 3.1.0 enables some ESM support but I'm still seeing this NextJS issue on that version 🤷 https://github.com/yarnpkg/berry/blob/master/CHANGELOG.md#bugfixes

I tried adding pnpEnableEsmLoader: true to my .yarnrc.yml but didn't seem to resolve this issue

hoangvvo commented 2 years ago

next-connect is provided with both ESM and commonjs version.

As it appears to be due to Yarn PnP not handling ESM probably, we can try to disable ESM in Next.js.

One can also try to patch next-connect package.json to remove any reference of ESM (remove the exports field, leaving only the main field)

{
  "name": "next-connect",
  "version": "0.11.0",
  "description": "The method routing and middleware layer for Next.js (and many others)",
  "keywords": [
    "javascript",
    "nextjs",
    "middleware",
    "router",
    "connect"
  ],
-  "type": "module",
  "main": "dist/index.cjs",
-  "module": "dist/index.js",
  "types": "dist/index.d.ts",
  "files": [
    "dist"
  ],
-  "exports": {
-    ".": {
-      "require": "./dist/index.cjs",
-      "import": "./dist/index.js"
-    }
-  }
}
ceefour commented 2 years ago

Using nodeLinker: pnp with nextjs 12.x is quite flaky. But sometimes when you're lucky, with the addition of yarn unplug next, it can work.

MatsG23 commented 2 years ago

next-connect is provided with both ESM and commonjs version.

As it appears to be due to Yarn PnP not handling ESM probably, we can try to disable ESM in Next.js.

One can also try to patch next-connect package.json to remove any reference of ESM (remove the exports field, leaving only the main field)

{
  "name": "next-connect",
  "version": "0.11.0",
  "description": "The method routing and middleware layer for Next.js (and many others)",
  "keywords": [
    "javascript",
    "nextjs",
    "middleware",
    "router",
    "connect"
  ],
-  "type": "module",
  "main": "dist/index.cjs",
-  "module": "dist/index.js",
  "types": "dist/index.d.ts",
  "files": [
    "dist"
  ],
-  "exports": {
-    ".": {
-      "require": "./dist/index.cjs",
-      "import": "./dist/index.js"
-    }
-  }
}

Sounds promising. How to test that? I've never made a own npm plugin and have no idea how to do that.

merceyz commented 2 years ago

Should have been fixed in https://github.com/yarnpkg/berry/pull/3667

yarn set version canary && yarn install

Does a library author have to config their library is a specific way to work with Yarn PnP?

@hoangvvo No, as long as you declare all the dependencies you use and use Node builtins to deal with resolving modules everything should just work on its own

hoangvvo commented 2 years ago

Should have been fixed in https://github.com/yarnpkg/berry/pull/3667

yarn set version canary && yarn install

Does a library author have to config their library is a specific way to work with Yarn PnP?

@hoangvvo No, as long as you declare all the dependencies you use and use Node builtins to deal with resolving modules everything should just work on its own

Awesome work! Thanks a lot

minkichoe commented 2 years ago

I fixed this issue after changing Docker settings. But I think merceyz's solution is right for the fundamental problem and solution. Thanks!

My new Dockerfile

FROM node:alpine

WORKDIR /app

COPY package.json .yarnrc.yml .pnp.loader.mjs ./
COPY .yarn .yarn

RUN yarn set version berry
RUN yarn install

EXPOSE 3000

COPY entrypoint.sh /entrypoint.sh