I’m sure at one point or another we have all run into the inevitable problem, “I wanna server-side render my React app, but I really want code-splitting too.” — Welcome to hell.
I myself, like many, many others in the React community, faced the same dilemma.
And many of us have probably been holding out for React 17 to save the day… according to the guys working on it, it’s a long way away. Tears were shed, the reality was faced 😂.
- Im a Senior Frontend Engineer at Fiverr’s Research and Development wing, based in NYC. I contribute to both Product and Platform.
- Before that, I was a founding member of a digital agency. From the garage to successful business with its own building, 50–60 people working there, and eventually expanding operations to three continents.
- I’ve had the pleasure of working with and ultimately designing complex architectures for companies in the $20bn range.
- I like complex stuff, not complicated, complex.
There were options out there, to identify the best choice , I put together a list of base requirements.
- Granular control & flexibility
- Scalable and plays nicely with containerized architecture
- Robust for platform development, day to day simplicity for feature development.
- Ability to access verbose outputs from low-level APIs
Pretty hard to find, especially when you are dealing with this new craze of micro-frontend architecture. I need something architects love just as much as junior devs.
I chose the Universal Family by FaceySpacey (James Gillmore). The Universal Family gave me the best of both worlds.
I went with the inventor, not some other library. However, I didn’t just use Universal. I joined forces with its author. Working tirelessly and earning the privilege to be a maintainer of the Universal Family officially.
I have been following James Gillmore and his work for a very long time. For those of you who don’t know, Webpack’s
resolveWeak, that was thanks to James. It was HIS pull request. Essentially, he’s the damn inventor of code-split server-side rendering for React. Every other solution I had looked at just used
resolveWeak. Don’t get me wrong, forks and adaptions are an important part of a healthy open-source community. Hell, I fork and iterate over open source code all the time.
While our solution is more complex during the initial implementation, it provides more flexibility in the long run:
- You can use dynamic expressions inside imports
- Create user-land HOCs
- Hoist statics
- Double render with Apollo
- Leverage callbacks when rendering
- Split reducers
- And so on…
Universal supports a plethora of features that other code splitting packages require workarounds to achieve.
Universal is robust and feature-packed, whereas the other solutions are minimal.
After setting up a pretty fantastic POC Node infrastructure with stunning code-splitting and an incredibly easy way to code-split for developers, it was safe to say that I was pretty happy with my little experiment. Patching issues along the way to make Universal ready for large-scale, intricate systems.
But then Webpack 4 was released. Webpack 4 pretty much re-wrote all things chunking, considering we were a code spitting system… Universal didn’t work when I attempted to update. Game over?
The Universal Family now supports aggressive code-splitting!
As of June 4, 2018,We released a major update of babel-plugin-universal-import which now Supports Webpack 4
As of June 5, 2018, We released a major update of extract-css-chunks-webpack-plugin which now Supports Webpack 4
As of June 12, 2018, We released a major update of webpack-flush-chunks which enables developers to use Universal with more complex / aggressive code-splitting tactics.
So, how did we solve this?
Pretty much, extract-css-chunks-webpack-plugin was the main issue… We needed a Webpack 4 solution to CSS chunking.
We all know Webpack is slated for better CSS handling at some point in the future. We dont know when but nobody seems to be saying its anytime soon. So we cant bank on vaporware
Check out out the Universal family (start here): https://github.com/faceyspacey/react-universal-component
I’m sure you are thinking, “Just use mini-css-extract.” Yeah. I tried that, and it did the job of code splitting CSS, but there was no Hot Module Reloading (HMR)…. Ouch
“But there’s style-loader, just use it for dev builds!”
Well yeah, there is that. But c’mon
- No Source Maps
- Cant edit styles in chrome devtools
- String injection into the DOM
- Styles overwriting styles as more inline code is appended.
- Not something reputable companies like
At Fiverr, or any large company, there’s some common sense goals I aim to achieve.
Within the scope of CSS, here’s what I want:
- Improve DX and mitigate risk.
- Avoid as much inconsistency between local and production.
- Avoid hard to debug CSS, additional memory and slowdowns in the client.
- Don’t interfere with CSS’s cascading goodness ( keep styles in an inheritable order)
- Improve long term cacheing
- Speed up builds
You need dev builds to function as close as possible to production builds. You need a good end-to-end system that stands up to the heat of high traffic. Relying on a build that isn’t as close as it can be to production opens you up to risk you may only catch after you deployed a $100k mistake.
Whats the point in a great system if the DX (Developer Experience) is not where it needs to be? I looked around at how to make mini-css-extract hot reload. Quite frankly, I was disappointed, not by the great work of Sokra, but by the fact that its just more work and still clunky. I just want it to work. Like seriously, what doesn’t HOT reload these days 😂
Essentially we took mini-css, changed it up a little, and added Automatic HMR injection into it.
A valid question. I’ll answer it in two parts.
Why use mini-css-extract and modify it?
- The API is familiar, less friction & drop-in replacement.
- It’s well written, fast, simple.
- Webpack’s author was involved directly.
Why not PR Webpack?
- I will. But that’s not ideal for our agenda right now.
- I want control over the architecture of Universal.
- Mini-css seems low-priority, it’s a stopgap solution until Webpack natively handles css, which they have planned for some point in the future.
- Mini-css will likely change over time, our use cases and agendas might not match.
FaceySpacey is back — the truth is that he never actually left. He has had his hands full with more exciting things. Universal is fantastic, and now with a committed team, we can innovate faster, look after our faithful dependents better, and achieve our ultimate goals of improving the React workflow.
A big part of that is Rudy (previously redux-first-router)
Rudy doesn’t have a whole lot left on the task list! However, Rudy is only one of three vital parts of Respond Framework which, we hope, will genuinely change React development.
We are just a team distributed of coders. Our reward for all this work is pretty simple. We are all coders and we kinda just want to make some tools that make our lives easier, and in turn, we want to make all of your lives easier too. React is fantastic, but its time for its “Rails” moment. Its time for the next big thing.
Follow me on Twitter ScriptedAlchemy
Having lived most of my life in Cape Town, South Africa. Where technological constraints made many things seem impossible, this quote sounds applicable.