storybookjs / storybook

Storybook is the industry standard workshop for building, documenting, and testing UI components in isolation
https://storybook.js.org
MIT License
84.02k stars 9.23k forks source link

Cant add aliases in storybook config #11989

Closed toastyboost closed 3 years ago

toastyboost commented 4 years ago

Cant add aliases to storybook 6^ main.js

const path = require("path");

module.exports = {
  webpackFinal: async (config) => {
    config.resolve.alias = {
      ...config.resolve.alias,
      "~/": path.resolve(__dirname, "../src/"),
    };
    config.resolve.extensions.push(".ts", ".tsx");
    return config;
  },
};
{
  "compilerOptions": {
    "allowJs": false,
    "allowSyntheticDefaultImports": true,
    "baseUrl": ".",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "isolatedModules": true,
    "jsx": "react",
    "lib": ["dom", "dom.iterable", "esnext"],
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "rootDirs": ["src", "stories"],
    "outDir": "./dist",
    "strict": true,
    "skipLibCheck": true,
    "target": "es6",
    "typeRoots": ["./node_modules/@types"],
    "paths": {
      "~/": ["./src/"]
    }
  },
  "exclude": ["./node_modules", "./dist"],
  "include": ["src", "stories"]
}

error

Module not found: Error: Can't resolve '~/' in '/Users/user/dev/storybook-starter/stories'
 @ ./stories/develop.stories.tsx 54:0-31 57:13-22 72:25-34
 @ ./stories sync nonrecursive ^\.\/(?:(?!\.)(?=.)[^/]*?\.stories\.(ts|tsx))$
 @ ./.storybook/generated-stories-entry.js
 @ multi ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/storybook-init-framework-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/common/config.js-generated-other-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/react/config.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addArgs.js-generated-other-entry.js ./.storybook/preview.js-generated-config-entry.js ./.storybook/generated-stories-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined

files

Screenshot 2020-08-13 at 18 33 57

What i am doing wrong?

tooppaaa commented 4 years ago

Without thinking too far, I think updating config object might not work as expected. A simple workaround for you @toastyboost

webpackFinal: async (config) => {
    return {
      ...config,
      resolve: {
        ...config.resolve,
        alias: {
          ...config.resolve?.alias,
          ...aliases,
        },
      },
    };
  },

In addition with 0 config typescript, you no longer need config.resolve.extensions.push(".ts", ".tsx");

silouanwright commented 4 years ago

I'm running into this as well and I assume this will break a lot of Storybook devs experience.

    config.resolve.modules = [
      ...(config.resolve.modules || []),
      path.resolve('../')
    ]

This is what I had before that allowed to resolve to my root path properly, but for whatever reason this doesn't help in my upgrade.

ndelangen commented 4 years ago

If someone could create a reproduction repo, that'd be super helpful fixing this bug.

if this doesn't work

const path = require("path");

module.exports = {
  webpackFinal: async (config) => {
    config.resolve.alias = {
      ...config.resolve.alias,
      "~/": path.resolve(__dirname, "../src/"),
    };
    config.resolve.extensions.push(".ts", ".tsx");
    return config;
  },
};

then that's a bug.

gavmck commented 4 years ago

I just came across this after having some issues having upgraded storybook to 6.

Turned out my problem was an incorrect resolve function for whatever reason.

My main.js is in .storybook and I am using this function:

function resolve(dir) {
  return path.join(__dirname, dir)
}

Example:

alias: {
  '@': resolve('../src'),
},

Otherwise the same setup described by @ndelangen above and it is working.

chrisbutler commented 4 years ago

this was working fine for me with Storybook 5.x, but is now broken in 6.x

the exact scenario described by @ndelangen is not working for me, so i'm inclined to believe that this is a bug

i also still see info => Using default Webpack setup. in the console, even though i am providing custom config like so:

const webpackConfig = require('../.webpack/client.js');

module.exports = {
  webpackFinal: (config) => ({
    ...config,
    resolve: {
      ...config.resolve,
      ...webpackConfig.resolve,
      alias: {
        ...config.resolve.alias,
        ...webpackConfig.resolve.aliases,
      },
    },
  }),
  //other config properties
}
mattrothenberg commented 3 years ago

I'm also running into this issue, having tried the solution here https://github.com/storybookjs/storybook/issues/11989#issuecomment-674833064.

@ndelangen Check out this repro repository – https://github.com/mattrothenberg/sb6-resolve-alias-error

You should be able to clone, run yarn && yarn storybook and see that the tilde ("~") alias doesn't resolve for the Button component.

JanJakes commented 3 years ago

I think the problem may be trailing slashes. Try using ~ and ../src/ exactly. It seems to work for me in all the variants below (Storybook 6.0.21 and 6.0.27).

Shortest:

webpackFinal: async (config) => {
  config.resolve.alias['~'] = path.resolve(__dirname, '../src/');
  return config;
},

Short:

webpackFinal: async (config) => {
  config.resolve.alias = {
    ...config.resolve?.alias,
    '~': path.resolve(__dirname, '../src/'),
  };
  return config;
},

Longer:

webpackFinal: async (config) => ({
  ...config,
  resolve: {
    ...config.resolve,
    alias: {
      ...config.resolve?.alias,
      '~': path.resolve(__dirname, '../src/'),
    },
  },
}),
jkincheloe33 commented 3 years ago

Above solution works for me except when I add an additional folder layer. @images fails for me


webpackFinal: async config => {
    config.resolve.alias['@components'] = path.resolve(__dirname, '../components')
    config.resolve.alias['@images'] = path.resolve(__dirname, '../assets/images')
    return config
},
monolithed commented 3 years ago

Here is a workaround for using aliases from tsconfig (*.mdx stories are supported as well):

const {TsconfigPathsPlugin} = require('tsconfig-paths-webpack-plugin');

module.exports = {
    stories: [
        '../src/**/*.stories.@(ts|tsx|mdx)'
    ],
    addons: [
        '@storybook/addon-essentials'
    ],

    webpackFinal: async (config) => {
        [].push.apply(config.resolve.plugins, [
            new TsconfigPathsPlugin({extensions: config.resolve.extensions})
        ]);

        return config;
    }
};

I guess this should be added to Storybook docs.

shilman commented 3 years ago

cc @jonniebigodes

MariuzM commented 3 years ago

@monolithed posted a nice solution, but i wish this was cleaner with my prettier formating it looks like this

  webpackFinal: async (config) => {
    ;[].push.apply(config.resolve.plugins, [
      new TsconfigPathsPlugin({ extensions: config.resolve.extensions }),
    ])

    return config
  },

Apart from that for TypeScript users this is how i have it setup: in tsconfig.ts

{
  "compilerOptions": {
    "baseUrl": "./src",
  },
}

and in ./.storybook/main.js

const { TsconfigPathsPlugin } = require('tsconfig-paths-webpack-plugin')

module.exports = {
  stories: ['../**/src/**/*.stories.@(ts|tsx|js|jsx|mdx)'],
  addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
  webpackFinal: async (config) => {
    ;[].push.apply(config.resolve.plugins, [
      new TsconfigPathsPlugin({ extensions: config.resolve.extensions }),
    ])

    return config
  },
}

Update: looks like this is a cleaner version

  webpackFinal: async (config) => {
    config.resolve.plugins = [new TsconfigPathsPlugin({ extensions: config.resolve.extensions })]
    return config
  },
jonniebigodes commented 3 years ago

I've been doing some testing with this and there seems to be somewhat of an issue. I've setup a repo here to triage this. So far from my testing i saw a couple of things:

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "[object Object]".] { code: 'ERR_UNHANDLED_REJECTION' } error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.


- I factored in the comments above with the `tsconfig-paths-webpack-plugin` usage and included a [branch](https://github.com/jonniebigodes/storybook-ts-alias/tree/alias_plugin_webpack) in the repo to do additional testing. Based on the configuration provided i'm faced with the following issue once i run `yarn storybook`:
```shell
info @storybook/react v6.0.28
info 
info => Loading static files from: /Users/myUser/myFolder/example/public .
info => Loading presets
info => Loading presets
info => Loading config/preview file in "./.storybook".
info => Loading config/preview file in "./.storybook".
info => Adding stories defined in ".storybook/main.js".
info => Loading Webpack configuration from `node_modules/react-scripts`
info => Removing existing JavaScript and TypeScript rules.
info => Modifying Create React App rules.
info => Using default Webpack setup.
webpack built d661ea12d96509bc01c5 in 17766ms
✖ 「wdm」: Hash: d661ea12d96509bc01c5
Version: webpack 4.44.2
Time: 17766ms
Built at: 18/11/2020 17:38:57
                                          Asset      Size        Chunks                                Chunk Names
                            asset-manifest.json  1.18 KiB                [emitted]                     
                                    iframe.html  2.92 KiB                [emitted]                     
            main.d661ea12d96509bc01c5.bundle.js   133 KiB          main  [emitted] [immutable]         main
        main.d661ea12d96509bc01c5.bundle.js.map  52.9 KiB          main  [emitted] [dev]               main
    runtime~main.d661ea12d96509bc01c5.bundle.js  35.1 KiB  runtime~main  [emitted] [immutable]         runtime~main
runtime~main.d661ea12d96509bc01c5.bundle.js.map  36.3 KiB  runtime~main  [emitted] [dev]               runtime~main
        static/media/code-brackets.2e1112d7.svg  1.42 KiB                [emitted] [immutable]         
               static/media/colors.a4bd0486.svg  8.31 KiB                [emitted] [immutable]         
             static/media/comments.a3859089.svg  1.49 KiB                [emitted] [immutable]         
            static/media/direction.b770f9af.svg  1.25 KiB                [emitted] [immutable]         
                 static/media/flow.edad2ac1.svg  1.36 KiB                [emitted] [immutable]         
               static/media/plugin.d494b228.svg  2.12 KiB                [emitted] [immutable]         
                 static/media/repo.6d496322.svg   1.6 KiB                [emitted] [immutable]         
             static/media/stackalt.dba9fbb3.svg  2.49 KiB                [emitted] [immutable]         
    vendors~main.d661ea12d96509bc01c5.bundle.js  7.98 MiB  vendors~main  [emitted] [immutable]  [big]  vendors~main
vendors~main.d661ea12d96509bc01c5.bundle.js.map  8.03 MiB  vendors~main  [emitted] [dev]               vendors~main
Entrypoint main [big] = runtime~main.d661ea12d96509bc01c5.bundle.js runtime~main.d661ea12d96509bc01c5.bundle.js.map vendors~main.d661ea12d96509bc01c5.bundle.js vendors~main.d661ea12d96509bc01c5.bundle.js.map main.d661ea12d96509bc01c5.bundle.js main.d661ea12d96509bc01c5.bundle.js.map
[0] multi ./node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/storybook-init-framework-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/common/config.js-generated-other-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/react/config.js-generated-other-entry.js ./node_modules/@storybook/addon-links/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addArgs.js-generated-other-entry.js ./node_modules/@storybook/addon-backgrounds/dist/preset/defaultParameters.js-generated-other-entry.js ./.storybook/preview.js-generated-config-entry.js ./.storybook/generated-stories-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined ./node_modules/react-scripts/node_modules/react-dev-utils/webpackHotDevClient.js 184 bytes {main} [built]
[./.storybook/generated-stories-entry.js] 2.88 KiB {main} [built]
[./.storybook/preview.js-generated-config-entry.js] 5.04 KiB {main} [built]
[./.storybook/storybook-init-framework-entry.js] 2.51 KiB {main} [built]
[./node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js] 500 bytes {vendors~main} [built]
[./node_modules/@storybook/addon-actions/dist/preset/addArgs.js-generated-other-entry.js] 2.44 KiB {vendors~main} [built]
[./node_modules/@storybook/addon-actions/dist/preset/addDecorator.js-generated-other-entry.js] 2.45 KiB {vendors~main} [built]
[./node_modules/@storybook/addon-backgrounds/dist/preset/defaultParameters.js-generated-other-entry.js] 2.45 KiB {vendors~main} [built]
[./node_modules/@storybook/addon-docs/dist/frameworks/common/config.js-generated-other-entry.js] 2.45 KiB {vendors~main} [built]
[./node_modules/@storybook/addon-docs/dist/frameworks/react/config.js-generated-other-entry.js] 2.45 KiB {vendors~main} [built]
[./node_modules/@storybook/addon-links/dist/preset/addDecorator.js-generated-other-entry.js] 2.44 KiB {vendors~main} [built]
[./node_modules/@storybook/core/dist/server/common/polyfills.js] 120 bytes {vendors~main} [built]
[./node_modules/@storybook/core/dist/server/preview/globals.js] 93 bytes {vendors~main} [built]
[./node_modules/react-scripts/node_modules/react-dev-utils/webpackHotDevClient.js] 8.01 KiB {vendors~main} [built]
[./node_modules/webpack-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined] (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined 7.68 KiB {vendors~main} [built]
    + 1773 hidden modules

ERROR in ./src/components/ComponentAlias.stories.mdx
Module not found: Error: Can't resolve '@components/MyOtherComponent' in '/Users/myUser/myFolder/example/src/components'
 @ ./src/components/ComponentAlias.stories.mdx 11:0-64 12:52-68 29:15-31 56:13-29
 @ ./src sync ^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.mdx)$
 @ ./.storybook/generated-stories-entry.js
 @ multi ./node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/storybook-init-framework-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/common/config.js-generated-other-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/react/config.js-generated-other-entry.js ./node_modules/@storybook/addon-links/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addArgs.js-generated-other-entry.js ./node_modules/@storybook/addon-backgrounds/dist/preset/defaultParameters.js-generated-other-entry.js ./.storybook/preview.js-generated-config-entry.js ./.storybook/generated-stories-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined ./node_modules/react-scripts/node_modules/react-dev-utils/webpackHotDevClient.js

ERROR in ./src/pages/MyPage.stories.tsx
Module not found: Error: Can't resolve '@components/MyOtherComponent' in '/Users/myUser/myFolder/example/src/pages'
 @ ./src/pages/MyPage.stories.tsx 52:0-64 77:62-78
 @ ./src sync ^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx))$
 @ ./.storybook/generated-stories-entry.js
 @ multi ./node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/storybook-init-framework-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/common/config.js-generated-other-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/react/config.js-generated-other-entry.js ./node_modules/@storybook/addon-links/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addArgs.js-generated-other-entry.js ./node_modules/@storybook/addon-backgrounds/dist/preset/defaultParameters.js-generated-other-entry.js ./.storybook/preview.js-generated-config-entry.js ./.storybook/generated-stories-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined ./node_modules/react-scripts/node_modules/react-dev-utils/webpackHotDevClient.js

ERROR in ./src/pages/MyPage.tsx
Module not found: Error: Can't resolve '@components/MyOtherComponent' in '/Users/myUser/myFolder/example/src/pages'
 @ ./src/pages/MyPage.tsx 7:0-64 49:37-53
 @ ./src/pages/MyPage.stories.tsx
 @ ./src sync ^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx))$
 @ ./.storybook/generated-stories-entry.js
 @ multi ./node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/storybook-init-framework-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/common/config.js-generated-other-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/react/config.js-generated-other-entry.js ./node_modules/@storybook/addon-links/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addArgs.js-generated-other-entry.js ./node_modules/@storybook/addon-backgrounds/dist/preset/defaultParameters.js-generated-other-entry.js ./.storybook/preview.js-generated-config-entry.js ./.storybook/generated-stories-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined ./node_modules/react-scripts/node_modules/react-dev-utils/webpackHotDevClient.js

ERROR in ./src/pages/MyPage.stories.tsx
Module not found: Error: Can't resolve '@images/image_2.jpg' in '/Users/myUser/myFolder/example/src/pages'
 @ ./src/pages/MyPage.stories.tsx 53:0-41 73:10-16
 @ ./src sync ^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx))$
 @ ./.storybook/generated-stories-entry.js
 @ multi ./node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/storybook-init-framework-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/common/config.js-generated-other-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/react/config.js-generated-other-entry.js ./node_modules/@storybook/addon-links/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addArgs.js-generated-other-entry.js ./node_modules/@storybook/addon-backgrounds/dist/preset/defaultParameters.js-generated-other-entry.js ./.storybook/preview.js-generated-config-entry.js ./.storybook/generated-stories-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined ./node_modules/react-scripts/node_modules/react-dev-utils/webpackHotDevClient.js

ERROR in ./src/pages/MyPage.stories.tsx
Module not found: Error: Can't resolve '@images/image_3.jpg' in '/Users/myUser/myFolder/example/src/pages'
 @ ./src/pages/MyPage.stories.tsx 54:0-41 74:10-16
 @ ./src sync ^\.(?:(?:^|\/|(?:(?:(?!(?:^|\/)\.).)*?)\/)(?!\.)(?=.)[^/]*?\.stories\.(js|jsx|ts|tsx))$
 @ ./.storybook/generated-stories-entry.js
 @ multi ./node_modules/@pmmmwh/react-refresh-webpack-plugin/client/ReactRefreshEntry.js ./node_modules/@storybook/core/dist/server/common/polyfills.js ./node_modules/@storybook/core/dist/server/preview/globals.js ./.storybook/storybook-init-framework-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/common/config.js-generated-other-entry.js ./node_modules/@storybook/addon-docs/dist/frameworks/react/config.js-generated-other-entry.js ./node_modules/@storybook/addon-links/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addDecorator.js-generated-other-entry.js ./node_modules/@storybook/addon-actions/dist/preset/addArgs.js-generated-other-entry.js ./node_modules/@storybook/addon-backgrounds/dist/preset/defaultParameters.js-generated-other-entry.js ./.storybook/preview.js-generated-config-entry.js ./.storybook/generated-stories-entry.js (webpack)-hot-middleware/client.js?reload=true&quiet=false&noInfo=undefined ./node_modules/react-scripts/node_modules/react-dev-utils/webpackHotDevClient.js
Child HtmlWebpackCompiler:
                          Asset     Size               Chunks  Chunk Names
    __child-HtmlWebpackPlugin_0  6.4 KiB  HtmlWebpackPlugin_0  HtmlWebpackPlugin_0
    Entrypoint HtmlWebpackPlugin_0 = __child-HtmlWebpackPlugin_0
    [./node_modules/html-webpack-plugin/lib/loader.js!./node_modules/@storybook/core/dist/server/templates/index.ejs] 2.19 KiB {HtmlWebpackPlugin_0} [built]

WARN Broken build, fix the error above.
WARN You may need to refresh the browser.

If anyone could share the repo, or take a look at the one i've mentioned we would have a better understanding of what's going on and i could document this accurately.

Stay safe

vkotlyar3 commented 3 years ago

Storybook version 6.1 I also faced with alias problems, but fixed that using approach below.

TypeScript Storybook use different paths to tsconfig, for TsconfigPathsPlugin he uses tsconfig.app.json For redefine config, just add to main.js next code

const TsconfigPathsPlugin = require("tsconfig-paths-webpack-plugin");
.....
webpackFinal: async (config, { configType }) => {
    config.resolve.plugins.push(new TsconfigPathsPlugin({
      configFile: './.storybook/tsconfig.json',
    }));

    return config;
  }

SCSS

webpackFinal: async (config) => {
    config.resolve.alias['@someAlias'] = path.resolve(__dirname, '../path')
    return config;
  }

Also, there are two configs of webpack: managerWebpack and webpackFinal

falsy commented 3 years ago

@vkotlyar3 thank you~

jonniebigodes commented 3 years ago

@vkotlyar3 that might work, but and if you allow me a couple of questions:

The reasoning behind this is that when a Storybook user initializes Storybook with Angular he gets the following: angular-storybook

And with React this:

react-ts-storybook

And to avoid introducing confusion when documenting it's best to get a clearer picture.

vkotlyar3 commented 3 years ago

@vkotlyar3 that might work, but and if you allow me a couple of questions:

  • is the code that you posted is based off angular?
  • or if not and you're using React you moved over the file and adjusted accordingly?

Yes, @jonniebigodes, my way works for Angular set up

jonniebigodes commented 3 years ago

that's what i thought. But in this case as we're dealing with versioned documentation and what works for one, might not work for others. But this is a good start angular is covered. All that is missing is a way to handle the other frameworks.

Smolations commented 3 years ago

This could be an issue in 5.x as well, which is the reason I ended up finding this thread. On v5.3.19, I have a custom webpack config that has worked fine up to this point. For some reason, I can't get aliases to work for sb addons, which I am developing locally. I must apologize for not having a repro repo, but the project is job-related and can't be shared in entirety. Luckily, others have produced their own repro repos which I hope will be sufficient. Anywho, on to my issue! 😋

Added alongside other addons, in .storybook/addons.js:

import '../lib/storybook-addons/my-local-addon/register';

In my custom webpack config, .storybook/webpack.config.js:

config.resolve.alias.mocks = path.resolve(__dirname, '..', '__mocks__');

As a part of my custom webpack config, I've found it helpful to save both the original and modified storybook webpack configs in a temp directory for validation/debugging purposes. Here's the relevant generated config:

  resolve:
   { extensions: [ '.mjs', '.js', '.jsx', '.json' ],
     modules:
      [ ... ],
     alias:
      { 'babel-runtime/core-js/object/assign':
         '/Volumes/projects/my-project/node_modules/@storybook/core/node_modules/core-js/es/object/assign.js',
        react: '/Volumes/projects/my-project/node_modules/react',
        'react-dom':
         '/Volumes/projects/my-project/node_modules/react-dom',
        mocks: '/Volumes/projects/my-project/__mocks__' } },  // <-- here it be!

My local addon uses a library of mocks, so it tries to pull files from those directories, which use the mocks alias for some imports. Up to this point, I was doing testing with these mock files within stories, with no issues. However, when I reached a point where I was ready to integrate those mocks with my custom addon (and so import from those modules), I started receiving storybook build errors:

ERROR in ./__mocks__/api/register-mock.js
Module not found: Error: Can't resolve 'mocks/axios' in '/Volumes/projects/my-project/__mocks__/api'
  // ...stacktrace...
   @ ./lib/storybook-addons/my-local-addon/register.js
   @ ./.storybook/addons.js

Perhaps this is simply a limitation of a local addon? I guess I was under the impression that the custom webpack config was responsible for ALL the code I bring into storybook, but it seems I may have been mistaken.. 🙈

ashernguyen commented 3 years ago

Do we have any update for this issue? I'm still facing this issue with latest Storybook version. I believe this issue happens to multiple layer folders structure as @jkincheloe33 mentioned above.

Above solution works for me except when I add an additional folder layer. @images fails for me

webpackFinal: async config => {
    config.resolve.alias['@components'] = path.resolve(__dirname, '../components')
    config.resolve.alias['@images'] = path.resolve(__dirname, '../assets/images')
    return config
}
sdwvit commented 3 years ago
trailing slash in alias key was the problem for me: before after
config.resolve.alias["@commons/"] = path.resolve(__dirname, '../commons/src/'); config.resolve.alias["@commons"] = path.resolve(__dirname, '../commons/src/');
TheDutchCoder commented 3 years ago

This works properly for me on the latest version:

const path = require("path")

module.exports = {
  "webpackFinal": async (config) => {
    config.resolve.alias['#'] = path.resolve(__dirname, '../src')
    config.resolve.alias['#components'] = path.resolve(__dirname, '../src/components')
    return config
  }
}
Alecell commented 3 years ago

@TheDutchCoder seems like the config.resolve.alias['#'] = path.resolve(__dirname, '../src') doesn't have any effect.

What the effect this shoud reach? Removing that line everything keeps working fine.

camslice commented 3 years ago

As per @TheDutchCoder , this works for me using Storyboard v6.2.9 and Vue 2. It configures an alias from @ to ../src and allows you to write relative imports from any folder, eg:

import Button from '@/components/atoms/Button.vue';
import MyMixin from '@/mixins/my-mixin.js';

Add a webpackFinal key to ./.storybook/main.js:

const path = require("path")

module.exports = {
  "stories": [ ... ],
  "addons": [ ... ],
  "webpackFinal": async (config) => {
    config.resolve.alias['@'] = path.resolve(__dirname, '../src')
    return config
  }
}
mdirshaddev commented 3 years ago

This works properly for me on the latest version:

const path = require("path")

module.exports = {
  "webpackFinal": async (config) => {
    config.resolve.alias['#'] = path.resolve(__dirname, '../src')
    config.resolve.alias['#components'] = path.resolve(__dirname, '../src/components')
    return config
  }
}

I was struggling to find the solution and then i found yours solution. By the way i was missing a double quotes on webpackFinal. That's all. Thanks

maxim-c commented 3 years ago

hmmm, I can't get why alias @ works but ~ is not... Spend pretty good amount of time trying to setup with ~, thinking that something wrong with config itself... 🤯

works fine:

    config.resolve.alias['@'] = path.resolve(__dirname, '../src')

    config.module.rules.push({
      test: /\.scss$/,
      use: [
        'style-loader', 
        'css-loader',
        {
          loader: "sass-loader",
          options: {
            additionalData: '@import "@/assets/scss/utils";',
          },
        }, 
      ],
    });

SassError: SassError: Can't find stylesheet to import: @import "~/assets/scss/utils";

    config.resolve.alias['~'] = path.resolve(__dirname, '../src')

    config.module.rules.push({
      test: /\.scss$/,
      use: [
        'style-loader', 
        'css-loader',
        {
          loader: "sass-loader",
          options: {
            additionalData: '@import "~/assets/scss/utils";',
          },
        }, 
      ],
    });
hcl-bpchasse commented 3 years ago

When I encountered this issue, I was expecting the aliases to resolve correctly for files in the .storybook/ directory. What I found was that it seems the aliases are not for resolving in the .storybook/ directory (.storybook "config" files?), but instead for resolving when running the Storybook webpack build (npm run storybook).

One thing we noted was that our custom React "add on" component, being registered in.storybook/register.js, was being resolved like the other files in the .storybook/ directory.

We resolved our issue by using relative paths for .storybook/ files and addons, and are leveraging aliases, as described in this issue, for our actual Storybook story files.

For our working Storybook webpack server aliases, we configured .storybook/main.js like:

// .storybook/main.js

const webpackConfig = require('../webpack.config')

module.exports = {
  webpackFinal: (config) => {
    config.resolve.alias = {
      ...webpackConfig.resolve.alias,
      ...config.resolve.alias,
    }
    return config;
  },
};

Thanks All!

faatihi commented 3 years ago

Late to the party, but I had to change my choice of character. I changed $ to @ and it now works fine

-   config.resolve.alias['$'] = path.resolve(__dirname, '../src/components/')
-   config.resolve.alias['$utils'] = path.resolve(__dirname, '../src/utils/')
+   config.resolve.alias['@'] = path.resolve(__dirname, '../src/components/')
+   config.resolve.alias['@utils'] = path.resolve(__dirname, '../src/utils/')
gaurav5430 commented 3 years ago

Had the same issue in latest storybook 6.3.3 In my case the issue was the trailing slash, as mentioned by @JanJakes here: https://github.com/storybookjs/storybook/issues/11989#issuecomment-715524391

instead of ~/ i had to use ~

lParanhos commented 3 years ago

For me, using NextJs, this is solved the problem:

/.storybook/main.js

const path = require('path')
module.exports = {
   // ...others configs

    webpackFinal: async (config) => {
      config.resolve.modules = [
        ...(config.resolve.modules || []),
        path.resolve(__dirname, "../"),
      ];

      config.resolve.alias = {
        ...config.resolve.alias,
        '@components': path.resolve(__dirname, '../components'),
        '@public': path.resolve(__dirname, '../public'),
        '@styles': path.resolve(__dirname, '../styles')
      }

      return config;
    },
  }
Razzwan commented 2 years ago

It works without slashes:

const path = require("path");

module.exports = {
    addons: ['@storybook/addon-links', '@storybook/addon-essentials'],
    stories: ['../src/**/*.stories.@(js|jsx|ts|tsx)'],
    webpackFinal: (config) => {
        config.resolve.alias = {
            ...config.resolve.alias,
            "~": path.resolve(__dirname, "../src"),
        };
        return config;
    },
};
TheDutchCoder commented 2 years ago

I don't work with webpack anymore, but doesn't the ~ character have a special meaning in a webpack context? I thought it wasn't meant to be used as an identifier for your own resolvers (same as with @since npm packages can now use that and result in conflicts).

It's also the reason I used # in my example.

shirakaba commented 2 years ago

Here's how I was able to resolve tsconfig path aliases in a React + TypeScript + Vite Storybook project, in case any other lost souls end up here: How to resolve aliases in Storybook? – Stackoverflow. The thread also details equivalent solutions for Webpack.

shadowmint commented 2 years ago

I know this is an old ticket with numerous "try this" things listed in it, but fundamentally, the issue is reproducible by doing this:

npm init vue@latest

Select:

✔ Project name: … foo
✔ Add TypeScript? … Yes
✔ Add JSX Support? … No 
✔ Add Vue Router for Single Page Application development? … No 
✔ Add Pinia for state management? … No 
✔ Add Vitest for Unit Testing? … No 
✔ Add Cypress for both Unit and End-to-End testing? … No 
✔ Add ESLint for code quality? … No

Now install storybook

cd foo
npx storybook init
npm install

Now create a basic component:

<script setup lang="ts">
import HelloWorld from '@/components/HelloWorld.vue'  // <--- Using an alias
</script>

<template>
  <div>
    <hello-world msg="hi"/>
  </div>
</template>

<style scoped>
</style>

and a basic story:

import Hello from './Hello.vue';

export default {
    title: 'Hello',
    component: Hello,
    argTypes: {},
};

export const Default = () => ({
    components: {Hello},
    setup: () => ({}),
    template: `<hello/>`,
});

and run:

npm run storybook

You will see:

Screen Shot 2022-05-31 at 8 34 08 pm
8:33:34 pm [vite] Internal server error: Failed to resolve import "@/components/HelloWorld.vue" from "src/components/Hello.vue". Does the file exist?
  Plugin: vite:import-analysis
  File: /Users/doug/dev/nest-rpg/foo/src/components/Hello.vue
  1  |  import { defineComponent as _defineComponent } from "vue";
  2  |  import HelloWorld from "@/components/HelloWorld.vue";
     |                          ^
  3  |  const _sfc_main = /* @__PURE__ */ _defineComponent({
  4  |    name: "Hello",

...but why?

Well, bluntly because the storybook configuration is wrong.

The automatically generated vite config for storybook and the vite config from the vue scaffold are different; the scaffold looks like this:

export default defineConfig({
  plugins: [vue(), vueJsx()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})

and tsconfig.json that says:

  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },

and .storybook/main.js doesn't load that file. Or doesn't process it. Or something.

If you modify main.js to have this import, it works, eg:

const { mergeConfig } = require('vite');
const path = require("path");

module.exports = {
  ...
  "features": {
    "storyStoreV7": true
  },
  async viteFinal(config, { configType }) {
    return mergeConfig(config, {
      resolve: {
        alias: { '@': path.resolve(path.dirname(__dirname), "src")},
      },
    });
  },

So is this an issue or not?

Well, lets put it this way.

Anyone who uses the official (https://vuejs.org/guide/quick-start.html#with-build-tools) vue scaffold, with the official storybook install (https://storybook.js.org/docs/vue/get-started/install), will get an 'out of the box' copy of storybook that is broken.

I don't know why this issue is closed with 'completed' because a work around exists, but, for anyone who finds this post, no, it's not just you, it's broken.

If you feel strongly about it, consider opening a new issue, a PR...

...but please appreciate that fundamentally the reason this is broken is because the alias is defined in the root configuration files, and those files are not used by storybook; the version generated by storybook does not include them; if you want to fix it, you need to look at what your configuration actually does and back port that into the storybook config, not just randomly copy and paste changes from this thread.

sunflowerseastar commented 9 months ago

I'm using Nextjs 14 and Storybook 7.5/7.6, and my co-worker really wanted a custom ~ alias for whatever reason, sigh. Anyway, I got this working like this, based on @lParanhos solution above (thank you!):

  webpackFinal: async (config: any) => ({
    ...config,
    resolve: {
      ...config.resolve,
      alias: {
        ...config.resolve.alias,
        '~': path.resolve(__dirname, '../'),
      },
    },
  }),