webpackbabeljspreactcss-in-jsstyled-jsx

styled-jsx works inline but not as module


I've added styled-jsx to my Preact (set up with this TS template) project, and can style things inline via the <style> tag with no issues, e.g.:

    <div>
      <h1>Hello{name && `, ${name}`}!</h1>
      <form onSubmit={handleNameSubmit}>
        <input type="text" value={input} onInput={handleInput} />
        <button type="submit" className="test">
          Update {input && `as ${input}`}
        </button>
      </form>
      <style jsx>
        {`
          h1 {
            color: red;
          }

          .test {
            color: blue;
          }
        `}
      </style>
    </div>

But if I extract that style into a separate css variable (either in the same file or externally) while following their instructions I get the following error:

if you are getting this error it means that your `css` tagged template literals were not transpiled.

There's a few answers/solutions to it on SO and Github but they all involve changing the webpack config -- and I don't have a webpack config. Looks like there isn't one out of the box with preact-cli. I've added the babel rule to my babelrc as recommended:

{
  "presets": ["preact-cli/babel"],
  "plugins": [["styled-jsx/babel", { "optimizeForSpeed": true }]]
}

I didn't install any extra macros or plugins from babel, however, as that was not in the original instructions in the styled-jsx readme.


Solution

  • Using .babelrc isn't supported at the moment in Preact-CLI, though this is due to an odd bug that I haven't yet been able to track down. Sorry about that.

    You do however still have a way to edit the Webpack config, and that's with your preact.config.js, the docs for which can be found here. In your case, what you'll want is the following:

    preact.config.js

    export default (config, env, helpers) => {
        const { rule } = helpers.getLoadersByName(config, 'babel')[0];
        const babelConfig = rule.options;
    
        babelConfig.plugins.push(['styled-jsx/babel', { 'optimizeForSpeed': true }]);
    }
    

    Let me know if this fixes your issue.