Skip to content
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

[WIP] isomorphic-style-loader example #1664

Closed
wants to merge 3 commits into from

Conversation

timmywil
Copy link
Contributor

@timmywil timmywil commented Apr 8, 2017

This is a work in progress. I've got server-rendering working, but only in production. The next.js hot-reloader in dev mode doesn't work with multiple webpack configs, but I'm looking into either updating that or working out a webpack config that will write CSS files correctly to dist.

First, I tried using emit-file-loader, writing both the output of css-loader and isomorphic-style-loader. The former isn't really what we want (because then what would be the point of using isomorphic-style-loader?), and the latter has require statements that are expected to only be used from within a bundle (with special characters and such in the URLs that only webpack understands).

So, I switched gears and created a separate config for CSS files. This bundled the CSS file to something workable. By the way, this separate CSS module is only necessary server-side. The client-side bundles included everything fine from the beginning.

This got me to a working page in production mode. But, depending on how I initialized the css property in pageWithStyles.js, it would either only work server-side, or only work client-side. There must be some race condition, but I need a deeper understanding of either next.js or react-dom's renderToString.

Basically, isomorphic-style-loader adds styles to the context through its own HOC's componentWillMount method. However, if I initialize css to an empty array in getInitialProps, it's like componentWillMount is not called server-side, but it does get called client-side. So, you see a flash of unstyled text.

If I use defaultProps, as you see in this PR, server-rendering works fine (componentWillMount is called server-side), but as soon as the client-side code executes, that css property gets cleared again and the styles disappear. I'm not sure how that can happen because I figured componentWillMount would be called again on the client on load, but I'm either wrong about that or something is setting CSS and then clearing it later, but before the first render.

Ref #1615

@timmywil timmywil changed the title [WIP] First pass at isomorphic-style-loader example [WIP] isomorphic-style-loader example Apr 8, 2017
@winglian
Copy link

winglian commented Apr 8, 2017

@timmywil if you look at RSK, the client side uses a different insertCSS function. That's probably the cause of the headache.

const insertCss = (...styles) => {
  const removeCss = styles.map(x => x._insertCss())
  
  return () => { removeCss.forEach(f => f()); }
}

@timmywil
Copy link
Contributor Author

timmywil commented Apr 8, 2017

@winglian It's not.

@lenny0702
Copy link

image
When I run this example, I stuck in this step, and the server is not up. Do you have any ideas?

@timmywil
Copy link
Contributor Author

@lenny0702 Right, this currently only works in production mode (npm run build && npm start) because next's custom hotreloader is reading the config and it doesn't expect multiple configs.

@winglian Sorry for the short answer. If I could just understand how the styles are getting cleared on the client-side on load, I think something like the insertCss function you showed would be helpful. It's disconcerting that some very small changes switch things up and make it work on the client, but not the server.

- I had to disable chunking. Maybe someone with more knowledge of
  chunk plugin config can restore it.
@timmywil timmywil force-pushed the isomorphic-style-loader branch from dcd0b90 to 84c1475 Compare April 11, 2017 17:18
@timmywil
Copy link
Contributor Author

I think I'm one step closer.

Try npm run build && npm start. Visit http://localhost:3000. The header should be red and there should be no flash of unstyled content.

I'm still working on getting npm run dev working.

- The hacks continue, but I just want to see it working at this point.
@timmywil
Copy link
Contributor Author

npm run dev now works, but does not hot-reload CSS. That's all that's left to get this to a working state. However–and this is a big however–I've had to do a few hacks to get this working (including removing webpack chunking, which may result in longer build times). In the end, I'm not sure I can recommend actually doing this unless someone comes up with suggestions for improvement.

@timneutkens
Copy link
Member

I'm going to close this for inactivity. Cleaning up old PRs. i'd love to take this in one day though ❤️

@lock
Copy link

lock bot commented May 10, 2018

This thread has been automatically locked because it has not had recent activity. Please open a new issue for related bugs and link to relevant comments in this thread.

@lock lock bot locked as resolved and limited conversation to collaborators May 10, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
examples Issue was opened via the examples template.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants