Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Turbopack does not handle CommonJS modules properly when "type": "commonjs" is specified in package.json #74062

Open
saoudi-h opened this issue Dec 18, 2024 · 1 comment · May be fixed by #74162
Labels
bug Issue was opened via the bug report template. Turbopack Related to Turbopack with Next.js.

Comments

@saoudi-h
Copy link

Link to the code that reproduces this issue

https://github.com/saoudi-h/commonjs-issue-next-turbopack

To Reproduce

Create a Next.js app using npx create-next-app.
Install Jotai (pnpm install jotai) or any other library that specifies "type": "commonjs" in its package.json.
Run the application with Turbopack enabled (next dev --turbopack).
Import the library into your project and attempt to use it.

Current vs. Expected behavior

Current Behavior: The application throws an error due to an incompatibility between the "type": "commonjs" field in the library's package.json and Turbopack's handling of ESModules. This breaks the development server and prevents the application from running.

Expected Behavior: Turbopack should handle CommonJS modules seamlessly, as per the Node.js module resolution standards, regardless of the "type" field in package.json.

Provide environment information

Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 11 Pro
  Available memory (MB): 32695
  Available CPU cores: 16
Binaries:
  Node: 20.11.1
  npm: 10.2.4
  Yarn: 1.22.19
  pnpm: 8.15.3
Relevant Packages:
  next: 15.1.1 // Latest available version is detected (15.1.1).
  eslint-config-next: 15.1.1
  react: 19.0.0
  react-dom: 19.0.0
  typescript: 5.7.2
Next.js Config:
  output: N/A

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

Turbopack

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

next dev (local)

Additional context

This issue was initially observed in a discussion in the Jotai repository. The maintainer pointed out that Turbopack does not respect the "type": "commonjs" field, leading to incompatibilities with libraries that follow the Node.js module conventions. While workarounds like patching the affected library or modifying its package.json exist, the root cause seems to be Turbopack's handling of CommonJS modules.

It would be great to address this issue as it could impact many libraries and developers using Turbopack in their Next.js projects.

@saoudi-h saoudi-h added the bug Issue was opened via the bug report template. label Dec 18, 2024
@github-actions github-actions bot added the Turbopack Related to Turbopack with Next.js. label Dec 18, 2024
@lubieowoce
Copy link
Member

lubieowoce commented Dec 19, 2024

Hmm, It looks like this is a bug in the transform we do when a 'use client' directive is encountered. I think what's happening is that we're creating a virtual file that uses ESM import/export syntax, but it's called proxy.js (not proxy.mjs), so the "type": "commonjs" makes turbopack "correctly" upset at the ESM syntax.


if we look at the full error message, we can notice it's happening in a that file doesn't actually exist in node_modules:

./node_modules/<SNIP>/jotai/esm/react.mjs/proxy.js
                                         ^^^^^^^^^
                                       this bit here! 
    

Specified module format (CommonJs) is not matching the module format of the source code (EcmaScript Modules)
The CommonJs module format was specified in the package.json that is affecting this source file or by using an special extension, but Ecmascript import/export syntax is used in the source code.
The module was automatically converted to an EcmaScript module, but that is in conflict with the specified module format. Either change the "type" field in the package.json or replace EcmaScript import/export syntax with CommonJs syntas in the source file.
In some cases EcmaScript import/export syntax is added by an transform and isn't actually part of the source code. In these cases revisit transformation options to inject the correct syntax.

here's the bit that adds the proxy.js suffix to the exiting module path
https://github.com/vercel/next.js/blob/c92e84529620e732309671baf93b9ae6b68e7544/crates/next-core/src/next_client_reference/ecmascript_client_reference/ecmascript_client_reference_proxy_module.rs/#L148-L152

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template. Turbopack Related to Turbopack with Next.js.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants