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. However, in my opinion, all seemed clunky to a degree. The lack of moving parts is great — but I needed the ability to get deep down into the cogs of a system. Big companies are not one size fits all, and nor are their platforms. That’s what I needed from a plugin — but it’s a double-edged sword. How so? Well, the fact that it is good for me doesn’t help development teams. Not very scalable, especially if you’ve got to teach a bunch of miscellaneous crap that’s so easy to break! Pretty hard to find the best of both worlds, especially when you are dealing with this new craze of micro-frontend architecture. In other words, I need something architects love just as much as junior devs. I want low-level as an architect, but as a frontend feature developer, I also want day-to-day simplicity in the trenches.
Ultimately, I chose the Universal Family by FaceySpacey (James Gillmore). The Universal Family gave me the best of both worlds.
I went with the inventor (Coca-Cola), not some other library (generic cola). I didn’t just use Universal, I joined forces with its author. I’ve been working tirelessly with him and earning the privilege to officially be a maintainer of the Universal Family.
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 as you can use dynamic expressions in imports, create userland HOCs, hoist statics, double render with Apollo, utilize callbacks when rendering, split reducers, the list goes on. Ultimately 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? LOL, more like just getting started.
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.
Primarily, I was after an easy win. 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
The goal was to provide our dependents with a fantastic solution.
Check out out the Universal family (start here): https://github.com/faceyspacey/react-universal-component
I’m sure you are thinking, “Dude just use mini-css-extract.” Lol. Yeah. I tried that, and it did the job of code splitting CSS, but there was no Hot Module Reloading (HMR)…. Dafuq?!
“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
I want to improve DX and mitigate risk. Fiverr (and any other company) isn’t the place to introduce serious inconsistencies, hard to debug CSS, additional memory and slowdowns in the client as it gets bigger and bigger. Beyond the basics, there are some excellent development practices and standards that should be followed. One is that we use inheritance and cascading! If my global styles are delivered from a CDN, and the development styles append in the wrong order…. Then suddenly the natural beauty of cascading gets blurred. If something, for some reason, isn’t visually correct, there are more variables to pinpoint the issue. You end up debugging a non-existent problem caused by an inconsistent build. What an absolute waste of time.
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. You cant just deploy a screwup. If you work at a big company, you’ll likely understand where I’m coming from, there’s a bigger picture to think about. 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, ouch! Yeah, you can roll back production, but damn, reverting master over an inconsistent build output isn’t what anyone wants. Luckily there’s almost always staging environments. However, you cant rely on a developer to follow the process, especially if you want to build something intended for diverse teams. Risk should be mitigated, right from the local environment.
I uphold professional standards and practices; a good process is a good process — have some standards, I was lucky enough to adopt many from some legends of frontend. You gotta be willing to accept better people with better ideas and opinions. Mine is ever changing — if your method is provably better then I’ll preach that. I do the best I know and always want to know better. I love being proved wrong!
It comes down to this, build the shit that companies would use. Not because you've gone corporate, but because if companies want to depend on your work, then your work must be good and solid. Look at the who depends/has depended on extract-css-chunks. Theres no shortage of companies in both the package and repos section. Theres many more who are not public too!
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.
Ultimately, FaceySpacey is back — the truth is that he never actually left. He has had his hands full with more exciting things. Universal is fantastic, now with a committed team, FaceySpacey is an even more powerful force to be reckoned with. With the added manpower, we are able to innovate faster, look after our faithful dependents better, and achieve our ultimate goals. We are the team who will fix modern React development once and for all.
A big part of that is Rudy (previously redux-first-router): https://github.com/faceyspacey/redux-first-router/tree/rudy-respond
Rudy doesn’t have a whole lot left on the task list! But ultimately Rudy is only one of three vital parts of Respond Framework which will truly change React development.
At the end of the day, 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 cool shit that makes 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.