Unused Server-Only Dynamic Import Inside `typeof window === 'undefined'` Causes Error
See original GitHub issueVerify canary release
- I verified that the issue exists in Next.js canary release
Provide environment information
$ npx --no-install next info
Operating System:
Platform: linux
Arch: x64
Version: #112-Ubuntu SMP Thu Feb 3 13:50:55 UTC 2022
Binaries:
Node: 14.18.1
npm: 6.14.15
Yarn: 1.22.17
pnpm: N/A
Relevant packages:
next: 12.1.6-canary.9
react: 18.0.0
react-dom: 18.0.0
What browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
Describe the Bug
Hi there! First of all, thanks for your continued effort on Next.js! 🙌 Really amazing framework.
Importing a client-only function in a Next.js page causes bundling of the server-only code contained within the typeof window === 'undefined'
check:
// pages/index.js
import { usedClientExport } from "../util/shared";
export default function IndexPage() {
usedClientExport();
return <div>Hello World</div>;
}
// util/shared.js
export async function unusedServerExport() {
if (typeof window === "undefined") {
await import("fs");
}
}
export function usedClientExport() {
console.log("yay");
}
Error:
./util/shared.js:3:10
Module not found: Can't resolve 'fs'
1 | export async function unusedServerExport() {
2 | if (typeof window === "undefined") {
> 3 | await import("fs");
| ^
4 | }
5 | }
6 |
Sandbox: https://codesandbox.io/s/recursing-lalande-k3w986?file=/util/shared.js
Expected Behavior
- Any unused functions (in my example,
unusedServerExport
) are removed using tree shaking or dead code elimination and not included in the client bundle - Any code in
typeof window === 'undefined'
is not included in the client bundle - No errors appear for any code that will not be included in the bundle (in either of 1 or 2)
To Reproduce
https://codesandbox.io/s/recursing-lalande-k3w986?file=/util/shared.js
‼️ This also occurs when using Babel instead of SWC:
https://codesandbox.io/s/unruffled-fire-jrkz7x?file=/pages/index.js (also here on StackBlitz: https://stackblitz.com/edit/nextjs-wmguir?file=pages%2Findex.js)
Potentially Related Issues
Issue Analytics
- State:
- Created a year ago
- Reactions:1
- Comments:10 (8 by maintainers)
Top Results From Across the Web
Window is not defined in nextJS - javascript - Stack Overflow
This code was working fine in ReactJS but not working in NextJS. Please help me to figure out this issue. import Link from...
Read more >How to solve "window is not defined" errors in React and Next.js
I initially tried to do if (typeof window !== undefined) and this ... your Scroll component using dynamic imports and the srr: false...
Read more >javascript - How to best import "server-only" code in Next.js? - Stack ...
let foo; if (typeof window === "undefined") { foo = require(". ... What about dynamically importing within getServerSideProps ? I'm using Next.js version ......
Read more >Firebase JavaScript SDK Release Notes - Google
Fixed a bug that caused Firebase SDKs to throw an error in Firefox browsers when ... This can be used to import data...
Read more >تويتر \ التغريدات مع الردود بواسطة Mark Lawlor (mark__lawlor@)
Playing around with adding type-safety Expo Router ... Unused Server-Only Dynamic Import Inside `typeof window === 'undefined'` Causes Error · Issue.
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Seems the main difference between the Babel/SWC approach is that the Babel transform we used to transform
typeof window
actually evaluates the expression and inlines the result whereas with the SWC transform it doesn’t evaluate it:Result with SWC:
Result with next/babel:
Ok, maybe the
.server.js
/.client.js
convention is something to adopt for non-React code then too, at least with Next.js apps, for now.We’ll also try out the hacky-feeling workaround to see if this is any more ergonomic.