Description
There's a complex problem with a not-rare case.
When you start your Nuxt app, Nuxt fills process.env with .env file content during Nuxt.config loading stage.
Process.env is available on the server, including code in the server bundle. So, many apps rely on this behavior for their private env vars.
Unfortunately, when you run Nuxt from inside your Jest test it behaves unexpectedly differently:
Nuxt still fills process.env, and it's even available inside the Jest test, but when it comes to the bundled server code there's a different copy of process.env that doesn't contain previously filled .env values.
The reason is doubled VM isolation usage - by Jest, then by vue-server-renderer (as a part of Nuxt).
Jest sets up a new VM context in the Node environment, so the global object (including global.process.env) inside our tests is not the initial one.
Nuxt runs fine in the same context, sharing the same global till a server render step, where runInThisContext is being called (by default). Unobviously, this method is not about sharing the current context, but the root one.
So, all the globals inside the client-side bundle are being shared on the top-level context ignoring the Jest isolation level.
It also can lead to conflicts between different tests.
It's hard to say, is it NTU's fault, Jest's, or VSR's? It looks like a bug in VSR, but only appears on the second isolation level, which hardly will be used outside nuxt+jest combo (which is NTU). So the issue is here
Workaround:
-
Use privateRuntimeConfig
-
Choose another vue-server-renderer strategy.
Nuxt.config { render: { bundleRenderer: { runInNewContext: 'once' } } } works (runInContext is called with the current global object under the hood).
This mode is closer to "run in this context" than runInThisContext :)