Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using the css Prop of @emotion/react and apply babel plugin #210

Closed
velopert opened this issue Jan 19, 2022 · 10 comments
Closed

Using the css Prop of @emotion/react and apply babel plugin #210

velopert opened this issue Jan 19, 2022 · 10 comments

Comments

@velopert
Copy link

velopert commented Jan 19, 2022

I am just submitting this issue so that it can be searched by others.

  1. Install these packages:
yarn add @emotion/babel-plugin @emotion/react
  1. Modify your vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    react({
      jsxImportSource: "@emotion/react",
      babel: {
        plugins: ["@emotion/babel-plugin"],
      },
    }),
  ],
});
  1. Modify tsconfig.json
  "compilerOptions": {
    "types": ["vite/client", "@emotion/react/types/css-prop"]
  1. Modify .story/book/main.js
const react = require("@vitejs/plugin-react");

module.exports = {
  stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
  framework: "@storybook/react",
  core: {
    builder: "storybook-builder-vite",
  },
  async viteFinal(config) {
    config.plugins = config.plugins.filter(
      (plugin) =>
        !(Array.isArray(plugin) && plugin[0]?.name.includes("vite:react"))
    );

    config.plugins.push(
      react({
        exclude: [/\.stories\.(t|j)sx?$/, /node_modules/],
        jsxImportSource: "@emotion/react",
        babel: {
          plugins: ["@emotion/babel-plugin"],
        },
      })
    );

    console.log(config.plugins);
    return config;
  },
};

That's it! Happy coding!!

@IanVS
Copy link
Member

IanVS commented Jan 19, 2022

Thanks for the tip!

@openscript
Copy link

I am just submitting this issue so that it can be searched by others.

Worked very well. Struggled, searched and found this. Thank you.

@bestickley
Copy link

bestickley commented Jan 27, 2022

Thank you for submitting this! Why doesn't adding:

"jsx": "react-jsx",
"jsxImportSource": "@emotion/react"

in tsconfig.json work as suggested in emotion docs?
(I'm actually not using storybook, just want to use emotion with Vite)

@thielium
Copy link

@bestickley I know it's been awhile since you asked, but in answer to your question: since storybook already defines the react plugin for vite, you have to remove it first, and then re-add it with a custom configuration.

If you do not omit the plugin that storybook provides, then vite complains about conflicting plugins.

@terenceodonoghue
Copy link

Sorry to resurrect this, but I found my way to this guide trying to add Emotion to my Vite Storybook setup. Unfortunately it doesn't seem to work when stories are written in MDX. After making this change all of my MDX stories fail to load, citing:

[vite] Internal server error: <path>/<file>.stories.mdx.jsx: importSource cannot be set when runtime is classic.

Would welcome some insight. I tried setting jsxRuntime: 'automatic' in the plugin config, but no joy.

@zygisau
Copy link

zygisau commented Aug 24, 2022

@terenceodonoghue Did you manage to solve your problem?

@terenceodonoghue
Copy link

terenceodonoghue commented Aug 25, 2022

@zygisau I wound up skipping this solution and instead inserting a JSX pragma at the top of every component file. This ensured they would render in MDX without needing to modify the Vite config.

// MyComponent.jsx
/** @jsxImportSource @emotion/react */

It's generating a lot of annoying console warnings for each component now...

warning: The JSX import source cannot be set without also enabling React's "automatic" JSX transform

...but it works.

@bdow
Copy link

bdow commented Aug 30, 2022

@terenceodonoghue - I was having the same problem and errors trying to get MDX working along side my stories. I saw your solution but I didn't really want to add that pragma to every file in our repo. I ended up trying out the MDX2 Opt-in feature, and the MDX stories started building without issues! Shout out to @IanVS for all the help on Discord.

Here is my entire storybook/main.js

const { mergeConfig } = require("vite");
const path = require("path");
const reactPlugin = require("@vitejs/plugin-react");

module.exports = {
  core: { builder: "@storybook/builder-vite" },
  stories: ["../src/**/*.stories.tsx"],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "storybook-addon-performance/register",
    "@storybook/addon-interactions",
  ],
  // https://storybook.js.org/docs/react/configure/typescript#mainjs-configuration
  typescript: { check: false },
  async viteFinal(config) {
    const mergedConfig = mergeConfig(config, {
      esbuild: {
        // ignoring console warns of "Top-level "this" will be replaced with undefined since this file is an ECMAScript module"
        // See https://github.com/vitejs/vite/issues/8644#issuecomment-1159308803
        logOverride: { "this-is-undefined-in-esm": "silent" },
      },
      resolve: {
        alias: {
          src: path.resolve(__dirname, "../src"),
        },
      },
    });

    return {
      ...mergedConfig,
      plugins: [
        // Filter out `vite:react-jsx` per suggestion in `plugin-react`...
        // "You should stop using "vite:react-jsx" since this plugin conflicts with it."
        // Implementation suggestion from: https://github.com/storybookjs/builder-vite/issues/113#issuecomment-940190931
        ...config.plugins.filter(
          (plugin) => !(Array.isArray(plugin) && plugin.some((p) => p.name === "vite:react-jsx")),
        ),
        reactPlugin({ exclude: [/\.stories\.tsx?$/, /node_modules/], jsxImportSource: "@emotion/react" }),
      ],
      optimizeDeps: [
        ...(mergedConfig.optimizeDeps ? mergedConfig.optimizeDeps.include || [] : []),
        "@emotion/react/jsx-dev-runtime",
      ],
    };
  },
  reactOptions: { fastRefresh: true, strictMode: false },
};

mistical2008 added a commit to mistical2008/react-storybook-emotion-issue that referenced this issue Nov 4, 2022
@SpookyJelly
Copy link

Do you guys can build .mdx file when tried this? Dunno why parsing error occurs on mdx files

@SpookyJelly
Copy link

Hey I finally made it. Just upgrade your storybook to latest version (7.0.beta). It respects tsconfig.json and vite.config.ts perfectly. All I have to do is just add jsxImportSource: "@emotion/react" in these 2 files. No edit needed in .storybook/main.ts. Now I am happy cause I finally get rid out emotion pragma in every React component file. It's an old issue, but I hope it helps someone.

If @terenceodonoghue is still having this problem, I want you to check my comment.

Storybook 7 migration guide

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants