streamich / nano-css

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

Can I prevent style insertion into the document? #157

Closed TheBosZ closed 6 years ago

TheBosZ commented 6 years ago

Let's say that I want to take advantage of the extract add on. How do I prevent style insertion when the rules are provided by including the generated stylesheet?

streamich commented 6 years ago

You can use hydrate addon and provide extracted CSS stylesheet like so:

const nano = create({
    sh: document.getElementById('extracted-style-sheet')
});
TheBosZ commented 6 years ago

According to the docs, sh should be the <style> element, not a <link src="stylesheet.css"> element.

When I try it anyway, I get an error:

TypeError: stylesheet.sheet is null

streamich commented 6 years ago

I updated hydrate addon. After installing it you will have .hydrate() function to which you can provide any <style> or <link> element.

Try inserting your external stylesheet like so:

<link rel="stylesheet" type="text/css" href="stylesheet.css" id="test">

And then hydrating it:

nano.hydrate(document.getElementById('test'));
TheBosZ commented 6 years ago

That looks promising, but I have an error when I run it:

TypeError: sh.sheet is null
./node_modules/nano-css/addon/hydrate.js/exports.addon/renderer.hydrate
C:/projects/nano-css-extract-demo/demo/node_modules/nano-css/addon/hydrate.js:11

   8 | var hydrated = {};
   9 | 
  10 | renderer.hydrate = function (sh) {
> 11 |     var cssRules = sh.cssRules || sh.sheet.cssRules;
  12 | 
  13 |     for (var i = 0; i < cssRules.length; i++)
  14 |         hydrated[cssRules[i].selectorText] = 1;

./src/nano.js
C:/projects/nano-css-extract-demo/demo/src/nano.js:18

  15 | addonJsx(nano);
  16 | const elem = document.getElementById('nano-css');
  17 | console.info(elem);
> 18 | nano.hydrate(elem);
  19 | 
  20 | 
  21 | console.info(nano);

My code is:

import { createElement } from "react";
import { create } from "nano-css";
import { addon as addonRule } from "nano-css/addon/rule";
import { addon as addonCache } from "nano-css/addon/cache";
import { addon as addonJsx } from "nano-css/addon/jsx";
import {addon as addonHydrate} from 'nano-css/addon/hydrate';

const nano = create({
  h: createElement,
  sh: document.getElementById('nano-style'),
});
addonHydrate(nano);
addonRule(nano);
addonCache(nano);
addonJsx(nano);
const elem = document.getElementById('nano-css');
console.info(elem);
nano.hydrate(elem);

console.info(nano);
nano.client = false;
const { put, rule, jsx } = nano;

export { nano, put, rule, jsx };
streamich commented 6 years ago

Which browser is that? How does HTML look like?

TheBosZ commented 6 years ago

This is in Firefox.

Here's the HTML:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    <title>React App</title>
    <link id="nano-css" href="./styles.css" />
    <style id="nano-style"></style>
</head>

<body>
    <noscript>
        You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
</body>

</html>
TheBosZ commented 6 years ago

I'll push up the code into a repo for you: https://github.com/TheBosZ/nano-css-problems

streamich commented 6 years ago

Try adding rel="stylesheet" type="text/css" to <link>.

TheBosZ commented 6 years ago

Yep, that did it! I totally missed that!

I'll consider this issue closed.