Closed Ponjimon closed 6 years ago
Hello! I'm not familiar with the details of next.js, so will have to do some reading before I can help.
To give you some immediate thoughts, the only component that uses window
is Mousetrap
, the library that I use to handle keyboard events, so try isolating code in src/client/debug/debug.js
that uses it. Will look closer and help you with this when I have more time on the weekend.
So I've tried isolating those window references, but I couldn`t make it build without errors. To test the server-side rendering, I used Yalc to link the repository as an NPM package which didn't work.
It's not clear how to publish the package correctly. I did yarn prepare && yarn prepublishOnly && yalc publish
But I always got some weird errors like
index.js?54be91e:369 babelHelpers is not defined
ReferenceError: babelHelpers is not defined
at http://localhost:4000/_next/1515594262237/page/game.js:22448:5
at Client (http://localhost:4000/_next/1515594262237/page/game.js:22568:4)
at Object.<anonymous> (http://localhost:4000/_next/1515594262237/page/game.js:12640:40)
at __webpack_require__ (http://localhost:4000/_next/1515594262237/manifest.js:714:31)
at fn (http://localhost:4000/_next/1515594262237/manifest.js:117:20)
at Object.<anonymous> (http://localhost:4000/_next/1515594262237/page/game.js:11616:22)
at Object.module.exports.Object.defineProperty.value (http://localhost:4000/_next/1515594262237/page/game.js:11718:30)
at __webpack_require__ (http://localhost:4000/_next/1515594262237/manifest.js:714:31)
at fn (http://localhost:4000/_next/1515594262237/manifest.js:117:20)
at Object.module.exports.Object.defineProperty.value (http://localhost:4000/_next/1515594262237/page/game.js:11562:18)
I tried removing the whole Debug component which helped with the "window not defined" problem, but then jumped to "document is not defined".
This is the part that deals with window in debug.js but it`s nearly not enough since Mousetrap has it inside as well.
saveState = () => {
const json = JSON.stringify(this.props.gamestate);
- window.localStorage.setItem('gamestate', json);
+ if (typeof window !== 'undefined') {
+ window.localStorage.setItem('gamestate', json);
+ } else {
+ console.warn('saveState executed before window was ready');
+ }
+
}
restoreState = () => {
- const gamestateJSON =
- window.localStorage.getItem('gamestate');
+ let gamestateJSON = null;
+ if (typeof window !== 'undefined') {
+ gamestateJSON = window.localStorage.getItem('gamestate');
+ } else {
+ console.warn('restoreState executed before window was ready');
+ }
+
if (gamestateJSON !== null) {
const gamestate = JSON.parse(gamestateJSON);
this.context.store.dispatch(restore(gamestate));
Server-side rendering is becomming a standard and it`s a problem in many React libraries. So I am giving up and will move probably move to some generic redux wrapper instead. Too bad, looked real nice...
The babelHelpers
error was due to a regression in package-lock.json that has since been fixed.
About the rest, I'll take a look once I've finished up the current set of features planned and see if we can get this working.
Also, how were you still having a Mousetrap dependency once you removed debug.js?
That would be awesome.
I just pasted the code for handling window in debug.js that wasn't enough since Moustrap is imported at the top of the file. Once I removed debug.js altogether, the Moustrap is no longer a problem. But anyway, I guess that is not really a solution, is it?
Maybe something like this could help... https://www.npmjs.com/package/window-or-global
I think all the code in src
should now be SSR-compatible. The examples
directory (not included in the NPM) uses react-router
, which I need to figure out how to use with SSR in order to properly demonstrate the feature. Any ideas or PR's are appreciated!
Ugh, had to revert. Looks like changing import 'somefile.css'
to require('somefile.css')
doesn't play well with how Rollup bundles the library.
The strategy I followed initially was to change all the CSS imports to something like:
if (typeof window !== 'undefined') {
require('somefile.css');
}
Any ideas on how to tackle CSS modules with SSR?
So I am trying to do SSR on my project. This is the code I wrote for SSR: https://github.com/Felizardo/turnato/blob/ssr/src/server.tsx#L30
This code is in a separate branch (ssr) because it does not work yet. I am getting this error trying to run the server:
ReferenceError: window is not defined at /home/felizardo/playground/turnato/node_modules/react-json-view/dist/main.js:1:149649 at /home/felizardo/playground/turnato/node_modules/react-json-view/dist/main.js:1:149611
So the error seems to be initially coming from a dependency of boardgame.io: react-json-view. I found this thread with other users having the same issue: https://github.com/mac-s-g/react-json-view/issues/121
In summary, this is happening because they have style loader module of webpack as their dependency. Even if we removed this dependency (react-json-view) from boardgame.io, this would not fix the issue as boardgame.io is itself dependent on style loader. So this goes back to what @nicolodavis was trying to do, avoid loading styles on the server.
Another option suggested on the thread was trying to use https://github.com/kriasoft/isomorphic-style-loader instead.
I will investigate those options further and let you know what I find :). SSR is very important for my project.
I got it working! :clap: Just submitted a PR, also managed to do a test so we dont break SSR in the future :laughing:
Hello,
I'm currently trying to use boardgame.io together with next.js. Because the
Server
part exports a Koa server, I went with this example to create a basic project: https://github.com/zeit/next.js/tree/canary/examples/custom-server-koaHowever, when I run the code, I get a
window is not defined
error. So I did some research and it's of course because Next.js is SSR and theClient
component requireswindow
to be present. So I made it like this:According to next.js, the client side code only runs, after
componentDidMount
has been triggered, so obviouslywindow
should be available, but somehow it isn't. Something insideClient
seems to run before that happens.