-
Notifications
You must be signed in to change notification settings - Fork 27k
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
Dynamic "import" creates a race condition with initial load requests #43284
Comments
I would propose to swap next.js/examples/with-msw/mocks/index.ts Lines 1 to 13 in 9fe5317
-const { worker } = await import('./browser')
+const { worker } = require('./browser') Does this have to do with dynamic |
// pages/_app.tsx
import { useEffect } from 'react'
import { AppProps } from 'next/app'
export default function App({ Component, pageProps }: AppProps) {
useEffect(() => {
// This is the recommended way to set up Web/Service Workers in the browser. See
// https://github.com/vercel/next.js/blob/canary/examples/with-web-worker/pages/index.tsx
// https://github.com/vercel/next.js/blob/canary/examples/with-service-worker/pages/index.tsx
if (process.env.NEXT_PUBLIC_API_MOCKING === 'enabled') {
Promise.all([import('msw'), import('../mocks/handlers')]).then(
([msw, { handlers }]) => msw.setupWorker(...handlers).start()
)
}
}, [])
return <Component {...pageProps} />
} // pages/_document.ts
export { default } from 'next/document'
if (process.env.NEXT_PUBLIC_API_MOCKING === 'enabled') {
require('msw/node')
.setupServer(...require('../mocks/handlers').handlers)
.listen()
} Since |
@balazsorban44 I tried your suggestion. But for client-side fetch requests, the client-side worker loads after the request is made on a next.js page (child component) via a I do have a working example that supports client-side fetch requests mocked via MSW. Take a look at mswjs/msw#1340 (comment) . But it does involve changing the default next.js setup, which isn't ideal. |
Thanks for the suggestion, @balazsorban44. I have a few concerns with the client-side part:
Overall, the setup grows in complexity and feels less and less as something we should recommend people to do manually (despite using the example template). I wonder, is there a way to abstract this? I was thinking of a webpack plugin or some other, more automated means to achieve this. |
|
I see. Do you have any opinion on abstracting this setup someplace else? Are there perhaps other tools that have a complex setup and utilize a different pattern than including it in the template directly? My main concern here is that this kind of setup is brittle due to its verbosity and internal detail awareness. Despite being a template, this is still the code that people will ship in their apps but they have, effectively, no authorship around this code. As a consequence, if there's an issue with this setup, it makes it hard to fix for people as they cannot re-apply the template and would have to apply whichever fix is appropriate manually. It really feels like something we should distribute rather than inline. I was thinking if adding a new entry to the webpack compilation wouldn't be beneficial here. Something like: // next.config.js
module.exports = {
webpack(config) {
config.entry.push('./msw.setup.js')
// Use a webpack plugin to create "msw.setup.js" module
// in the in-memory file system.
return config
}
} Then, on the consumer's side: // next.config.js
import { withMSW } from '@mswjs/webpack-plugin'
module.exports = withMSW() The plugin would ensure the correct module import and initialization, and the
|
I raised a different problem with Next 13 beta version here but it was closed down as being the same problem defined here, without any investigation or discussion. MSW works fine with the pages folder but fails with the app folder. Having integration with a tool like msw is going to be important to demonstrate the new fetching features and closing down an investigation into why msw is not compatible with Next 13 appDir will only delay progress in testing those features. @balazsorban44 please can you repoen that ticket relating to Next 13 until at least it is established these are the same problem. There is currently no msw+Next13 demo available and that issue could form the basis for it. You have closed down any possibility of that by closing the ticket. If you cannot guarantee that fixing the issue for Next 12 will fix issues for Next 13 beta specifically the app directory features with server side components then it is quite reasonable to have to open tickets relating to different major versions of Next. |
Replied there #43758 (comment) |
Since this issue has been sleeping for a while: has anyone been able to make any progress in adding MSW into a Nextjs 13 app directory structure? |
I think the official line is that the MSW maintainer will wait until the I don't have enough Node knowledge to know if this will work, but I was wondering about using this trick https://jake.tl/notes/2021-04-04-nextjs-preload-hack#using-preloading to 'preload' MSW in dev mode with a |
The @philwolstenholme 's stance is correct. At the moment, I don't see Next.js providing library authors with the alternative to @philwolstenholme, regarding the module preloading, what you're suggesting will work for Node.js but in Node.js things are already synchronous and working well. It is the browser integration that suffers from this race condition between:
That being said, you can give the preloading a try! If it works, it may be a reasonable workaround until a better solution is found. |
It would be great to hear the official Next team stance on the alternatives to the |
I've not had a chance to try it yet, and this is a bit out of my comfort zone, but I'm thinking of adding back the require, but then trying to use something like Re: using the Node preloading/ Edit: ah, maybe not! I got stuck trying to use ESM code with
|
I was able to fix the race condition in next v13.1.6 by using dynamic imports in if(process.env.NEXT_PUBLIC_API_MOCKING === 'enabled') {
const { initMocks } = await import('path/to/your/mocks');
await initMocks();
} In order to do this you will need to update |
I've just spotted https://nextjs.org/docs/app/building-your-application/optimizing/instrumentation – does this give a potential entry point for using MSW with the Next
|
@philwolstenholme, it looks like it does. Upon me trying the instrumentation hook, I've stumbled upon an issue that it tries to resolve browser exports of imported modules despite being a server-side hooks (wrote about it mswjs/msw#1644 (comment)). This may as well be a bug in Next or I may be using the hook incorrectly. I'm fairly confident in MSW's The fact that |
Verify canary release
Provide environment information
Which example does this report relate to?
with-msw
What browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
Describe the Bug
I believe due to #25607, MSW example has migrated from
require()
to dynamic importsimport()
in order to tree-shake MSW from production builds. That, however, introduced a different problem:await import()
is async, and there's no top-levelawait
to wait for theinitMocks()
function, there's a race condition created between the client-side code and the mocks being imported.This race condition manifests upon initial page requests as those may be ignored by MSW since the code is not done resolving
await import()
when those requests happen.Expected Behavior
To Reproduce
The text was updated successfully, but these errors were encountered: