15

I recently installed Storybook to my project

Dependencies and Dev Dependencies below:

"dependencies": {
    "@emotion/react": "^11.1.4",
    "@emotion/styled": "^11.0.0",
    "@fortawesome/fontawesome-svg-core": "^1.2.34",
    "@fortawesome/free-solid-svg-icons": "^5.15.2",
    "@fortawesome/react-fontawesome": "^0.1.14",
    "@hot-loader/react-dom": "^17.0.1",
    "node-sass": "^5.0.0",
    "react": "^17.0.1",
    "react-content-loader": "^6.0.1",
    "react-dom": "^17.0.1",
    "react-hot-loader": "^4.13.0",
    "react-router-dom": "^5.2.0"
  },
  "devDependencies": {
    "@babel/core": "^7.12.10",
    "@babel/preset-env": "^7.12.11",
    "@babel/preset-react": "^7.12.10",
    "@commitlint/cli": "^11.0.0",
    "@commitlint/config-conventional": "^11.0.0",
    "@emotion/babel-plugin": "^11.1.2",
    "@emotion/babel-preset-css-prop": "^11.0.0",
    "@emotion/jest": "^11.1.0",
    "@emotion/styled-base": "^11.0.0",
    "@storybook/addon-actions": "^6.1.15",
    "@storybook/addon-essentials": "^6.1.15",
    "@storybook/addon-links": "^6.1.15",
    "@storybook/preset-scss": "^1.0.3",
    "@storybook/react": "^6.1.15",
    "@wojtekmaj/enzyme-adapter-react-17": "^0.4.1",
    "babel-eslint": "^10.1.0",
    "babel-jest": "^26.6.3",
    "babel-loader": "^8.2.2",
    "babel-plugin-emotion": "^11.0.0",
    "babel-plugin-require-context-hook": "^1.0.0",
    "clean-webpack-plugin": "^3.0.0",
    "css-loader": "^5.0.1",
    "enzyme": "^3.11.0",
    "enzyme-to-json": "^3.6.1",
    "eslint": "^7.18.0",
    "eslint-config-prettier": "^7.1.0",
    "eslint-loader": "^4.0.2",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-jest": "^24.1.3",
    "eslint-plugin-react": "^7.22.0",
    "eslint-plugin-react-hooks": "^4.2.0",
    "html-webpack-plugin": "^5.0.0-alpha.3",
    "husky": "^4.3.8",
    "jest": "^26.6.3",
    "jest-prop-type-error": "^1.1.0",
    "prettier": "^2.2.1",
    "react-test-renderer": "^17.0.1",
    "sass": "^1.32.4",
    "sass-loader": "^10.1.1",
    "standard-version": "^9.1.0",
    "style-loader": "^2.0.0",
    "terser-webpack-plugin": "^5.1.1",
    "url-loader": "^4.1.1",
    "webpack": "^5.15.0",
    "webpack-bundle-analyzer": "^4.3.0",
    "webpack-cli": "^4.3.1",
    "webpack-dev-server": "^3.11.2"
  },

I built a simple button component that uses @emotion/styled for styling. I would like to add a story for this button, however, when running npm run storybook i get the following error

Module not found: Error: Can't resolve '@emotion/styled/base' in '/directory/to/Button'

This is what I am importing inside my button component:

import styled from '@emotion/styled';
import { useTheme } from '@emotion/react';

const StyledButton = styled.button`
  cursor: pointer;
  font-size: ${({ fontSize }) => fontSize};
`;

This is happening to other components that use @emotion/styled as well. Am i missing an extra dependency or do I need to add any presets to .babelrc file?

.babelrc:

{
  "presets": [
    "@babel/preset-env",
    "@babel/preset-react",
    "@emotion/babel-preset-css-prop"
  ],
  "env": {
    "test": {
      "plugins": ["require-context-hook"]
    }
  },
  "plugins": ["react-hot-loader/babel", "@emotion"]
}

Seb Orel
  • 171
  • 1
  • 2
  • 5
  • 2
    I'm trying to use storybook for the first time, and this is the first thing I hit. If you find a solution, please share. – user3141592 Jan 28 '21 at 21:23

4 Answers4

23

This is an issue caused by the break name change of emotion 11. So far storybook internally is still looking for the v10 names to integrate emotion packages. So you would have 2 options before storybook fixed it:

A. Downgrade to emotion 10.

B. A workaround:

// .storybook/main.js
const path = require("path");
const fs = require("fs");
const { merge } = require("webpack-merge");

function getPackageDir(filepath) {
  let currDir = path.dirname(require.resolve(filepath));
  while (true) {
    if (fs.existsSync(path.join(currDir, "package.json"))) {
      return currDir;
    }
    const { dir, root } = path.parse(currDir);
    if (dir === root) {
      throw new Error(
        `Could not find package.json in the parent directories starting from ${filepath}.`
      );
    }
    currDir = dir;
  }
}

module.exports = {
  stories: [
    "../stories/**/*.stories.mdx",
    "../components/**/*.stories.@(ts|tsx|mdx)",
  ],
  addons: ["@storybook/addon-links", "@storybook/addon-essentials"],
  webpackFinal: async (config) => {
    return merge(config, {
      resolve: {
        alias: {
          "@emotion/core": getPackageDir("@emotion/react"),
          "@emotion/styled": getPackageDir("@emotion/styled"),
          "emotion-theming": getPackageDir("@emotion/react"),
        },
      },
    });
  },
};

Yan
  • 577
  • 6
  • 14
6

I had this same issue. The @emotion/babel-plugin needs to be enabled as the top most plugin in your .babelrc file.

you have: "plugins": ["react-hot-loader/babel", "@emotion"]

should be: "plugins": [ "@emotion", "react-hot-loader/babel"]

Also, be sure to take a look at the instructions from emotion below

https://emotion.sh/docs/@emotion/babel-plugin

I'm using emotion libraries: "@emotion/react": "^11.1.5" "@emotion/styled": "^11.1.5" "@emotion/babel-plugin": "^11.2.0"

SamsonTheBrave
  • 527
  • 4
  • 10
0

I had a similar problem with the recent version of styled components with React. I resolved it by installing the babel plugin styled components

npm install --save-dev babel-plugin-styled-components

Then I re-ran the app and it worked again. I hope this will help you in your problem.

gstpsk
  • 3
  • 4
galo hernandez
  • 163
  • 1
  • 3
-1

To follow up with yan's comment.

You could write the webpack config as follow for better readability:

module.exports = {
  stories: [
    '../stories/**/*.stories.mdx',
    '../components/**/*.stories.@(ts|tsx|mdx)',
  ],
  addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
  webpackFinal: async (config) => {
    config.resolve.alias = {
      '@emotion/core': getPackageDir('@emotion/react'),
      '@emotion/styled': getPackageDir('@emotion/styled'),
      'emotion-theming': getPackageDir('@emotion/react'),
    };
    return config;
  },
};

Brian Lau
  • 11
  • 1
  • This answer falls flat because it is not known what you intend by `getPackageDir`, is this something that builds the path from the root of the project? Something with `require()`, `import()`, etc. – Bwvolleyball Jun 27 '23 at 14:48