-
Couldn't load subscription status.
- Fork 29.7k
Description
Verify canary release
- I verified that the issue exists in Next.js canary release
Provide environment information
$ /code/stateof/stateofjs-next/node_modules/.bin/next info
/bin/sh: 1: pnpm: not found
Operating System:
Platform: linux
Arch: x64
Version: #33~20.04.1-Ubuntu SMP Mon Feb 7 14:25:10 UTC 2022
Binaries:
Node: 14.18.2
npm: 6.14.15
Yarn: 1.22.5
pnpm: N/A
Relevant packages:
next: 12.1.1-canary.6
react: 17.0.2
react-dom: 17.0.2
Done in 1.15s.
What browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
Describe the Bug
I am building a library of components.
- Package "my-package-tsup" has shared (ESM, IIFE, CJS), client-only (ESM, IIFE) and server-only (CJS, ESM) exports
- "my-package-tsup/server" (CJS) depends on "my-package-tsup-dependency" (CJS and ESM).
- So, server entrypoints are using CJS, while I allow shared code to use either CJS or ESM, with an
exportsfield like this:
{
"name": "my-package-tsup",
"version": "1.0.0",
"description": "",
"main": "./dist/shared/index.js",
"type": "module",
"files": [
"dist/"
],
"exports": {
".": {
"node": "./dist/server/index.cjs",
"import": "./dist/shared/index.js"
},
"./server": "./dist/server/index.cjs", => this is the one that seems problematic.
"./client": "./dist/client/index.js"
},So, when importing "my-package-tsup/server", Next will correctly load the "dist/server/index.cjs" file. But when this CJS file require it's subdependency, using a require call, it will try to pick the .js ESM export instead of sticking to the .cjs CJS export.
Here is the package.json of the dependency:
{
"name": "my-package-tsup-dependency",
"version": "1.0.0",
"description": "",
"main": "./dist/shared/index.js",
"type": "module",
"files": [
"dist/"
],
"exports": {
".": {
"node": "./dist/server/index.cjs", => this is the one that should be preferred but instead Next.js complains about trying to require an ESM module. It might be tricked by the "type":"module" and not respect the exports for dependencies, while it works ok for top-level packages
"import": "./dist/shared/index.js"
},
"./server": "./dist/server/index.cjs",
"./client": "./dist/client/index.js"
},To rephrase this:
If a CJS top level package requires one if it's dependency, the exports field of the dependency does not seem to be respected. The ESM export will be loaded, instead of the CJS export.
Expected Behavior
CommonJS dependencies should also use the CommonJS export of their own subdependencies.
To Reproduce
It's not the easiest to reproduce:
- I can reproduce consistenly with this library of package: https://github.com/VulcanJS/vulcan-npm/tree/feature/datatable
git clone
git checkout feature/datatable
yarn && yarn run build && yarn run publish:local
It will rely on Yalc, so to test you'll need to set it up in a Next app.
Then import @vulcanjs/graphql/server in your Next app and you'll end up with the dreaded https://nextjs.org/docs/messages/import-esm-externals error
- I am trying to build a simpler repro here: https://github.com/VulcanJS/npm-the-right-way/tree/feature/try-dep
Clone, install, and open the "with-tsup" page http://localhost:3000/with-tsup
I seem to be able to have this message: Module not found: Package path . is not exported from package /code/npm-the-right-way/demo-next-app/node_modules/my-package-tsup-dependency (see exports field in /code/npm-the-right-way/demo-next-app/node_modules/my-package-tsup-dependency/package.json).
It's different from the error I have in the other package but could be related, as if "exports" were not understood correctly.
This issue might related: #34956