Path Alias React Fix Import @/
| |

How to resolve a path alias in Storybook

Introduction

Previously, we talked about how to define an alias in our React Project. Today, we will talk about how to configure storybook to resolve our path alias.

Prerequisites

If you haven’t configured an alias in your react project yet, then you should head to “How to Configure a Path Alias in a React Typescript App for cleaner imports” first, then come back here.

Another issue you might come up with in storybook

Also, since you are here, you may face an issue with react not starting up after installing storybook, and there is a solution to it here.

The Problem

If you attempted to import a component with a path alias into the stories folder,

import React from 'react';
import { ComponentStory, ComponentMeta } from '@storybook/react';
import { TodoItem } from '@/features/todos/components/TodoItem';

export default {
  title: 'Example/Todo Item',
  component: TodoItem,
} as ComponentMeta<typeof TodoItem>;

const Template: ComponentStory<typeof TodoItem> = () => <TodoItem />;

export const Primary = Template.bind({});

then you have likely encountered this error when starting storybook:

ERROR in ./src/stories/TodoItem.stories.tsx
Module not found: Error: Can't resolve '@/features/todos/components/TodoItem' in 'C:\\Users\\Administrator\\Documents\\GitHub\\my-app\\src\\stories'
 @ ./src/stories/TodoItem.stories.tsx 6:0-64 10:13-21 13:44-52
 @ ./src sync ^\\.(?:(?:^|[\\\\/]|(?:(?:(?!(?:^|[\\\\/])\\.).)*?)[\\\\/])(?!\\.)(?=.)[^\\\\/]*?\\.stories\\.(js|jsx|ts|tsx))$
 @ ./generated-stories-entry.js
 @ multi ./node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js ./node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ErrorOverlayEntry.js ./node_modules/@storybook/core-server/node_modules/@storybook/core-client/dist/esm/globals/polyfills.js ./node_modules/@storybook/core-server/node_modules/@storybook/core-client/dist/esm/globals/globals.js ./node_modules/webpack-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined ./storybook-init-framework-entry.js ./node_modules/@storybook/addon-docs/dist/esm/frameworks/common/config.js-generated-config-entry.js ./node_modules/@storybook/addon-docs/dist/esm/frameworks/react/config.js-generated-config-entry.js ./node_modules/@storybook/react/dist/esm/client/preview/config-generated-config-entry.js ./node_modules/@storybook/addon-links/dist/esm/preset/addDecorator.js-generated-config-entry.js ./node_modules/@storybook/addon-actions/dist/esm/preset/addDecorator.js-generated-config-entry.js ./node_modules/@storybook/addon-actions/dist/esm/preset/addArgs.js-generated-config-entry.js ./node_modules/@storybook/addon-backgrounds/dist/esm/preset/addDecorator.js-generated-config-entry.js ./node_modules/@storybook/addon-backgrounds/dist/esm/preset/addParameter.js-generated-config-entry.js ./node_modules/@storybook/addon-measure/dist/esm/preset/addDecorator.js-generated-config-entry.js ./node_modules/@storybook/addon-outline/dist/esm/preset/addDecorator.js-generated-config-entry.js ./.storybook/preview.js-generated-config-entry.js ./generated-stories-entry.js

The solution

To solve this issue, we will need to configure Storybook’s webpack to resolve the path alias. the concept is really similar to how we handled it with CRA earlier.

We do that by going to .storybook/main.js file, and adding the following configuration at the same level of stories and addons:

webpackFinal: async (config, { configType }) => {
    config.resolve.alias = {
      ...config.resolve.alias,
      '@': path.resolve(__dirname, "../src/"),
    };

    return config;
  }

and your configuration file will look something like this:

const path = require('path'); // 👈 import path

module.exports = {
  stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
  addons: [
    '@storybook/addon-links',
    '@storybook/addon-essentials',
    '@storybook/preset-create-react-app',
  ],
  framework: '@storybook/react',
  webpackFinal: async (config) => { // 👈 and add this here
    config.resolve.alias = {
      ...config.resolve.alias,
      '@': path.resolve(__dirname, '../src/'),
    };

    return config;
  },
};

Note that your .storybook/main.js file might be different, so do not copy and paste the entire configuration I have put up there, and only copy the webpackFinal part.

after doing so, storybook will be able to resolve our path alias!

Sing up to get an email notification when new content is published

Leave a Reply

Your email address will not be published. Required fields are marked *

Similar Posts