react-select: ScrollLock dist missing window undefined check
While attempting to upgrade react-select from version 2.4.4 to the latest 3.0.8 I’m running into issues with server side rendering and the following error:
ErrorDetails : ReferenceError: window is not defined
at ./node_modules/react-select/dist/base/dist/react-select-cac0a5ae.browser.esm.js (server.min.js:117809:17) -> var canUseDOM = !!(window.document && window.document.createElement);
We use this within a .Net CMS by way of ReactJS.Net so the window object is not available while it is being rendered on the server. The strange thing is that looking at the dist output from the npm package, the check for window being undefined isn’t there:
However, looking at the src it is:

The check did exist in the dist output of the 2.4.4 version so something with the build process may have been changed with version 3.0.0 that could have caused this? Thank you for looking at the issue!
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 6
- Comments: 15
The bundle you use on the server should be built with webpacks target: ‘node’ to resolve modules from ‘main’ or ‘module’ fields and not using client-side specific aliases.
Since you’re not running it under nodejs (ReactJS.NET does not provide full nodejs environment) you will get “require is not defined” when trying to use bundle built like this but there is away.
In the server build, keep target: ‘web’ (default when unspecified) but change resolve.aliasFields to an empty array, like this:
This way webpack will not use browser specific aliases when resolving react-select module… Ufff… 😃
In the code, it looks like there is a check for
typeof window !== 'undefined'However, in the compiled version I see:
Manually updating that code fixes the issue. Why does the code in the git repo differ from the built version on NPM?
Potential solution
For those looking for a potential fix, here are there solutions:
I think we are going to go with option 1…
UPDATE!
I found the culprit. Looks like preconstruct js is replacing things quietly:
https://github.com/preconstruct/preconstruct/blob/master/packages/cli/src/build/rollup.ts#L137
I do not agree with the assessment that the runtime environment not supporting a
windowfacade is the root cause of the issue. I do, however, agree that the root cause is not directly react-select, but would say is in fact thepreconstructbuild tool. If preconstruct is “correctly strippingtypeof windowchecks” then shouldn’t it be strippingwindow.documentchecks as well since that will also always exist in a browser context? It is unfortunate when tools try to be too ‘smart’ for their own good. I would accept this issue being closed on this basis though.It has been some time since I was in these codebases, and we’re on a pretty old version, so perhaps just need to take another look at the build and split ssr from client or, as @ianks suggested, see if the non-browser cjs version works.
@mgrzyb’s comment hits at the root issue and provides the best solution at the moment. See https://github.com/reactjs/React.NET/issues/1017 for more context.
I don’t believe that the fix to Preconstruct affects this issue because that fix is specific for UMD builds, and this issue is specific to non-UMD builds. Preconstruct is intentionally and correctly stripping
typeof windowchecks in thebrowserbuild since it’s assumed thatwindowwill be defined in abrowsercontext.I’m going to close this for now. I don’t believe that there’s anything else that
react-selectcan do to improve the situation. This is more of a ReactJS.NET/Webpack problem than a react-select problem since we are correctly assuming thatwindowis defined in aweb/browsercontext. Feel free to comment if you think there’s something that we can do to improve the situation and we will reopen the issue.Good news everyone! Looks like this behavior in
preconstructwas fixed in version 2.0.2 which was released within the last 24 hours. https://github.com/preconstruct/preconstruct/releases/tag/%40preconstruct%2Fcli%402.0.2I will inquire about getting its dependency updated from 1.0 to 2.0.2 to resolve this as well as any other changes that might be required.
Any headway on this? the alias and aliasFields method did not work for me when trying to upgrade to react-select 3.1.1. Still getting the
when trying to SSR
Why can’t you check if windows is defined on canUseDOM() function? I’d like to use some of hacks mentioned above but:
Same 😃