streamich / nano-css

Distilled CSS-in-JS for gourmet developers
The Unlicense
430 stars 24 forks source link

Server-rendering (a.k.a. hydrate) broken with virtual addon #213

Closed steadicat closed 1 year ago

steadicat commented 5 years ago

Unless I’m misunderstanding the (very scant) docs, when the virtual addon is enabled, hydrate does not seem to do what it's supposed to, i.e. it does not reuse the rules injected by the server into the DOM.

Here’s a simple test case to reproduce:

import { create } from "nano-css";
import { addon as addonRule } from "nano-css/addon/rule";
import { addon as addonVirtual } from 'nano-css/addon/virtual';
import { addon as addonHydrate } from "nano-css/addon/hydrate";

const style = document.createElement("style");
style.innerText = "._a {color: red;}._b {color: blue;}";
document.head.appendChild(style);

const nano = create({ sh: style });
addonRule(nano);
addonVirtual(nano);
addonHydrate(nano);

console.log(nano.rule({ color: "blue" }));
console.log(nano.rule({ color: "red" }));

(Run it in CodeSandbox)

I would expect color: blue to return the existing _a class and color: red to return the existing _b class. Instead they return new class names, which clash with the server-rendered ones. This breaks all the styles!

As an aside, the docs mention injecting nano.raw into the server rendered HTML. However, there is no mention of the fact that you're supposed to clear the accumulated rules after every page render, or how to do that. The only way I’ve found so far that works reliably is to create a new nano instance for every request.