styled-jsx: Can no longer inject style rule from a const string since version 2
It seems impossible to inject a style rule from a const string using styled-jsx version 2. Since this feature was supported in version 1, I would consider this a regression.
My personal use case is very simple, I would like to be able to define styles in CSS files to benefit from standard tooling for editing/linting, which are much harder to leverage with inline CSS-in-string or CSS-in-template-literal. I am sure that many other use cases would also be a fit.
Is this a bug? A known issue/limitation? I’d be happy to help either way, provided a little guidance.
Simple demonstration
You can also run a simple use case from this sample project (using Next.js): https://github.com/coox/styled-jsx-unexpected-curly-braces/blob/master/pages/index.js
Inline string: works!
The following rule injection works great, as expected:
<style jsx global>{'body { background-color: green; }'}</style>
Output:
<style id="__jsx-id">body{background-color:green;}</style>
Constant string literal: breaks!
However, just moving the string literal to a constant does not even build:
const greenBodyStyleSheet = 'body { background-color: green; }';
<style jsx global>{greenBodyStyleSheet}</style>
Output:
SyntaxError: The Identifier `greenBodyStyleSheet` is either `undefined` or it is not an external StyleSheet reference i.e. it doesn't come from an `import` or `require` statement`
Interpolated constant string in template literal: puzzles!
The closest I got was trying to interpolate the const inside a template literal. This does build, but the output was not what I was expecting:
const greenBodyStyleSheet = 'body { background-color: green; }';
<style jsx global>{`${greenBodyStyleSheet}`}</style>
Output (notice the unexpected surrounding curly braces):
<style id="__jsx-id">{body { background-color: green; };}</style>
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Reactions: 4
- Comments: 26 (3 by maintainers)
It was’t obvious for me when I started using styled-jsx that the build process you describe is pretty much the only way to achieve what I was trying to do… But thanks to this discussion, and with inspiration from Next.js’ with-global-stylesheet example, I managed to adapt your hypothetical build script as a webpack loader.
Now the following is possible, and what’s more, with hot module reload goodness!
I have updated my demo repo accordingly.
The principle is to leverage Webpack (in my case, through
next.config.js) to load CSS files as JavaScript modules exposing the style in acss-tagged template literal.This involves a combination of:
As far as I’m concerned, the issue documents ways to address style injection from an outside file, and can certainly be closed.
I might want to publish this simple loader (edit: done!), this could prove useful! Also, I might want to submit this as a Next.js example.
Thanks a lot for your help and explanations, @giuseppeg.
I finally upgraded my styled-jsx and implemented the following to load styles from dependencies:
I just realized that
csstemplate literal is responsible for generating the hash…butLeads to extra brackets as mentioned by @coox, if the style is imported using
global.I could come up with a more elaborate build process as suggested on this thread, but that would defeat the purpose of keeping it simple…
Hi @giuseppeg, this is a slightly different scenario than @coox’s situation, but kind of related and therefore I’d like your 👀 .
Background: Use
inline-importbabel plugin toimporta CSS file into a string, and then stick it inside<style jsx global>I added an example on next.js to load a CSS file located in
node_modules: https://github.com/zeit/next.js/pull/3157This uses
inline-importbabel plugin, which allows you toimporta CSS file into a string, and is based off a comment from here: https://github.com/zeit/next.js/issues/544#issuecomment-325512576 - a good use case is to quickly import libraries like normalize.css or other CSS libraries, without having to do extra work outlined in the previous with-global-stylesheet example.From the README on my PR
babel-plugin-inline-importusingnpmoryarn.babelrc:npmoryarn. In this example, I installedtachyons.node_modules/tachyons/css/tachyons.min.css.styled-jsx:Problem: It generates
__jsx-undefinedID onstyletagBut I’m not sure if this is considered as a hack and should be avoided. One reason I’m worried is that, if I run the above example, everything works perfectly except that the
idof the generatedstyletag is__jsx-undefined:Failed Attempts
Also, instead of
If I do
It generates a non-
undefinedidon thestyletag, but it generates extra curly braces at the beginning and at the end and therefore fails.It’d be great if you could take a look. It’s merged to master on next: https://github.com/zeit/next.js/tree/master/examples/with-global-stylesheet-simple