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

SyntaxError: Named export 'useRouter' not found #48801

Closed
1 task done
igordanchenko opened this issue Apr 24, 2023 · 17 comments · Fixed by #48811
Closed
1 task done

SyntaxError: Named export 'useRouter' not found #48801

igordanchenko opened this issue Apr 24, 2023 · 17 comments · Fixed by #48811
Assignees
Labels
bug Issue was opened via the bug report template.

Comments

@igordanchenko
Copy link

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #22 SMP Tue Jan 10 18:39:00 UTC 2023
Binaries:
  Node: 16.17.0
  npm: 8.15.0
  Yarn: 1.22.19
  pnpm: 7.1.0
Relevant packages:
  next: 13.3.2-canary.3
  eslint-config-next: N/A
  react: 18.2.0
  react-dom: 18.2.0

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

No response

Link to the code that reproduces this issue

https://codesandbox.io/p/sandbox/nextjs-router-esm-qoquxr?file=%2Fpages%2Findex.tsx

To Reproduce

  1. Open the sandbox: https://codesandbox.io/p/sandbox/nextjs-router-esm-qoquxr?file=%2Fpages%2Findex.tsx
  2. Observe the following error on the home page:
Server Error
SyntaxError: Named export 'useRouter' not found. The requested module 'next/router.js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'next/router.js';
const { useRouter } = pkg;
  1. Downgrade next version to 13.3.0 and the error goes away.

Describe the Bug

It appear that the release 13.3.1 includes certain changes to the named exports, so the following import no longer works in ESM:

import { useRouter } from "next/router.js";

The above code produces the following error:

Server Error
SyntaxError: Named export 'useRouter' not found. The requested module 'next/router.js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'next/router.js';
const { useRouter } = pkg;

A use-case for ESM import is a 3rd-party ESM-only component library that uses next/router.

Expected Behavior

Named exports should work in ESM as they used to prior to 13.3.1.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

@igordanchenko igordanchenko added the bug Issue was opened via the bug report template. label Apr 24, 2023
@chentsulin
Copy link
Contributor

chentsulin commented Apr 25, 2023

Next 13.3.1 breaks most of ESM apps using named imports to import Next.js CommonJS modules.

exports objects and named exports in compiled outputs are unanalyzable after next@13.3.1 due to the limitation of https://github.com/nodejs/cjs-module-lexer.

A similar issue in nextra: shuding/nextra#1785
Changes between Next 13.3.0 and 13.3.1 (using find-page-dir.js as example): https://www.diffchecker.com/3CguFwYr/

@chentsulin
Copy link
Contributor

chentsulin commented Apr 25, 2023

I believe this problem is caused by swc new module transformer which was introduced by this PR: swc-project/swc#4758

cc @kdy1 @magic-akari

@kdy1 kdy1 self-assigned this Apr 25, 2023
@magic-akari
Copy link
Contributor

The situation only occurs in the following circumstances:

  1. It uses the swc to transpile code from esm to cjs, but imports the transpiled cjs from esm.
  2. It is used in a nodejs environment, rather than a webpack-like bundler.
  3. It is used in a nodejs environment, but the importInterop: node option is not enabled.

I am considering which aspect of the isuue is the key factor.

@magic-akari
Copy link
Contributor

@kdy1 Do you believe that we should always emit the cjs-module-lexer hint, rather than only when importInterop: node is enabled?
This seems to make the output verbose and seems to be a catch-all for incorrect usage.

@kdy1
Copy link
Member

kdy1 commented Apr 25, 2023

Hmm.... Not sure. How another option (e.g. interopAnnotation) sounds to you, just for annotations?

@magic-akari
Copy link
Contributor

The optimal solution should be to set up the correct dual package.
import esm from esm, import cjs from cjs.

@kdy1
Copy link
Member

kdy1 commented Apr 25, 2023

But well, I think this is due to a wrong usage

@kdy1
Copy link
Member

kdy1 commented Apr 25, 2023

Yeah, I'll try it first

@kdy1
Copy link
Member

kdy1 commented Apr 25, 2023

How do you think about making importInterop: swc emit cjs hints?

@kdy1
Copy link
Member

kdy1 commented Apr 25, 2023

@magic-akari Sadly import esm from esm, import cjs from cjs. is not an option...
I think we may need one more import interop type, like full or any which is fully interopable (like importInterop: swc) and emits cjs module hints (like importInterop: node)

@magic-akari
Copy link
Contributor

@magic-akari Sadly import esm from esm, import cjs from cjs. is not an option... I think we may need one more import interop type, like full or any which is fully interopable (like importInterop: swc) and emits cjs module hints (like importInterop: node)

Both interopAnnotation boolean flag or new interop type are OK.
I prefer the boolean flag.

@kdy1
Copy link
Member

kdy1 commented Apr 25, 2023

Then let's use a boolean flag. Will you work on it? If not, I'll do it

@magic-akari
Copy link
Contributor

Then let's use a boolean flag. Will you work on it? If not, I'll do it

Yes, please assign to me.

@kdy1
Copy link
Member

kdy1 commented Apr 25, 2023

Thank you!

kdy1 pushed a commit to swc-project/swc that referenced this issue Apr 25, 2023
olayway added a commit to datopian/flowershow that referenced this issue Apr 26, 2023
- temporary solution to `SyntaxError: Named export 'useRouter' not
found` in versions 13.3.1+
- see this issue vercel/next.js#48801
@kodiakhq kodiakhq bot closed this as completed in #48811 Apr 27, 2023
kodiakhq bot pushed a commit that referenced this issue Apr 27, 2023
### What?

Enable import/export annotations for next.js files.

### Why?

It's required to allow importing next.js modules from node.
`cjs-module-lexer` needs these annotations to import CJS modules.

### How?

Closes WEB-949
Fixes #48801
@CobyPear
Copy link

CobyPear commented May 9, 2023

I'm still having issues trying to import a properly bundled package with esm and cjs into a nextjs app. It does seem like the new compiler has broken a lot of things that work fine in a "normal" nodejs + typescript app. Is there some guidance as to how to properly bundle and publish a library for Next 13.1+? Experiencing a fair amount of pain here trying to understand why importing a module to a nextjs app is so different than importing a module to a node app.

@igordanchenko
Copy link
Author

@CobyPear, it may be worth opening a separate ticket with specific example(s) as the issue described in this ticket was fixed in 13.3.2

@github-actions
Copy link
Contributor

github-actions bot commented Jun 9, 2023

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

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 9, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants