Recoil: [SSR][NextJS] Duplicate atom key during development and during production build in nextjs

Created on 12 Nov 2020  路  8Comments  路  Source: facebookexperimental/Recoil

Both during local development and also when building a production build, I鈥檓 getting a duplicate atom key for each key and each page using it after the first one.

I put together a quick sandbox to demonstrate the issue:
https://codesandbox.io/s/flamboyant-sea-tqlky

The errors show up in the build log, a quick way to test is using the integrated vercel deployment button.
Looking at the default nextjs example, I can鈥榯 spot any special settings there that would prevent whatever duplication is going on from happening: https://github.com/vercel/next.js/tree/canary/examples/with-recoil
That example however only makes use of recoil state on one page.

help wanted infra / build

Most helpful comment

@janus-reith - Sorry, I'm not very familiar with Next.JS or SSR.

Next.js has a concept of Pages. Imagine an SPA with multiple entry points, like an Admin and a Client App, both importing a module that declares a Recoil atom. So it doesn't have to be Next.js related.
Essentially it's a single Node.js process that executes JS files (build process) that eventually declare the same atom several times.

In development, when a file is changed, Next.js re-builds the relevant page entry file.
Because it's the same Node.js process, the atom has already been declared.
The same thing can happen with HMR when the file change triggers a rebuild of the whole file, or even when the atom is declared inside a component lifecycle/hook and only that is being hot-replaced.

Basically, I can't think of a solution to this problem besides providing a configuration setting to disable this check/warning.
At a minimum, developers should be able to disable it.
In Next.js or SSR that would be when running on the server.
In HMR, that would be when not in production env.

A zero config alternative might be tempting. E.g. relying on NODE_ENV=production like React does for it's optimizations.
It would probably solve the HMR issue, but not the build of Next.js, as that runs with NODE_ENV=production obviously.
Although, that would already be better than what we currently have.

All 8 comments

Also mentioned in:
https://github.com/facebookexperimental/Recoil/issues/213#issuecomment-659349900

This is how it looks like in the Vercel deployment build:
image

Has this been solved? I'm having the same issue.

@leonardomgt I was not able to solve this yet.

@drarmstr Tagging you as you seem to be a main contributor to this project, any chance you could have look at this? Thanks!

@janus-reith - Sorry, I'm not very familiar with Next.JS or SSR.

@janus-reith - Sorry, I'm not very familiar with Next.JS or SSR.

Next.js has a concept of Pages. Imagine an SPA with multiple entry points, like an Admin and a Client App, both importing a module that declares a Recoil atom. So it doesn't have to be Next.js related.
Essentially it's a single Node.js process that executes JS files (build process) that eventually declare the same atom several times.

In development, when a file is changed, Next.js re-builds the relevant page entry file.
Because it's the same Node.js process, the atom has already been declared.
The same thing can happen with HMR when the file change triggers a rebuild of the whole file, or even when the atom is declared inside a component lifecycle/hook and only that is being hot-replaced.

Basically, I can't think of a solution to this problem besides providing a configuration setting to disable this check/warning.
At a minimum, developers should be able to disable it.
In Next.js or SSR that would be when running on the server.
In HMR, that would be when not in production env.

A zero config alternative might be tempting. E.g. relying on NODE_ENV=production like React does for it's optimizations.
It would probably solve the HMR issue, but not the build of Next.js, as that runs with NODE_ENV=production obviously.
Although, that would already be better than what we currently have.

Related to #247

Thanks @drarmstr for the response nonetheless, and thanks @alexilyaev for the detailed description.

Regarding the multiple entry points, I wonder if this could be worked around by some more advanced tracing logic to distinguish actual redeclaration of the key from the same code being executed again using the callsite?
I guess that depending on the way atoms are initialized there could be cases where this is not fully reliable(e.g. some dynamic declaration with variable-based key names ), also I'm not sure about browser support but still, maybe that is a feasible approach to consider.

Me to for this issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ibnumusyaffa picture ibnumusyaffa  路  4Comments

karevn picture karevn  路  3Comments

thegauravthakur picture thegauravthakur  路  3Comments

adamkleingit picture adamkleingit  路  4Comments

adrianbw picture adrianbw  路  3Comments