Storybook: Static icons not loading in Storybook using Angular library

Created on 12 Jun 2020  路  4Comments  路  Source: storybookjs/storybook

I have an Angular library that uses Storybook to display all of the components. When trying to load local svg files, Storybook cannot find them.

  1. I have a library that has a few components with a .storybook directory along side it (The stories work fine when I run storybook, just the icon problem)
  2. In the html of the component I load the file in the img tag with the src pointing to my local svg file

I have attached my custom sass file into Storybook by importing it using the style-loader and sass loader in ./storybook/preview.js :
import '!style-loader!css-loader!sass-loader!../nav-design-sys/src/theme-light.scss';

And I pushed a new rule webpack in my ./storybook/main.js but that does not work, only the inline loaders work for sass :

config.module.rules.push({ test: /\.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'], include: path.resolve(__dirname, '../') });

I have also edited my main.js to configure webpack with a new rule for svg to see if I could replicate the same fix as above for my sass:

config.module.rules.push({ test: /\.svg$/, include: path.resolve(__dirname, '../'), use: [{ loader: 'svg-inline-loader' }, 'file-loader'], });

Once again the rule for webpack does not work.

I then tried the same approach using an inline loader. I used the svg-inline-loader and the file loader, but have had no luck in preview.js

import '!file-loader!svg-inline-loader!../assets/icon.svg';

This just came back in the chrome debugger as a 404 request stating that Icon.svg could not be found under this path:

Request URL: http://localhost:6006/assets/Call%20Center.svg

angular question / support

Most helpful comment

@calebedwards21 are you using windows? My fix looks like a windows path issue.

One way to avoid the problem is using the object syntax for the directory assets. When the object syntax is used, Storybook doesn't try to normalize it and just passes is straight through to Angular. So, in angular.json, if you have ..., "assets": [ "src/assets" ], ..., change it to ..., "assets": [ { "glob": "**/*", "input": "src/assets", "output": "assets" } ], ....

The problem seems to be how storybook is normalizing the assets to all be object format. When a directory path is checked, storybook's isDirectory() function returns false. Since storybook doesn't think it is a directory, it seems to be trying to treat the directory as a path. By formatting the path as a file asset object, Angular still treats it as a directory, is seems, and ends up making the parent directory the output.
In node_modules/@storybook/angular/dist/server/angular-cli_utils.js I looked at the call to isDirectory() and noticed it was passing a path like /E/Git/my-ng-app/src/assets, which returned false, because fs.statSync() threw an error that the file or directory didn't exist. @angular-devkit/core exports a function to map a path to the correct system format getSystemPath(). By using getSystemPath() I got the path E:\\Git\\my-ng-app\\src\\assets, which fs.statSync() was able to find and Storybook was able to normalize it correctly.

Until fixed, using the object syntax in angular.json is probably the best workaround, since it is a valid way of defining assets. If that isn't an option for your setup, you could add an npm "postInstall" script to replace line 31 in node_modules/@storybook/angular/dist/server/angular-cli_utils.js from if (isDirectory(resolvedAssetPath)) { to if (isDirectory(core_1.getSystemPath(resolvedAssetPath))) {, but I don't recommend changing files in node_modules unless absolutely necessary.

I can probably submit a PR later with the fix mentioned above, since it is only a 2 line change, but I need to update my nodejs before I can build and test storybook locally again. If this isn't unique to Angular cli, then there may be an earlier place to convert the path to the system path, but I haven't worked back through the code that far yet.

All 4 comments

@calebedwards21 are you using windows? My fix looks like a windows path issue.

One way to avoid the problem is using the object syntax for the directory assets. When the object syntax is used, Storybook doesn't try to normalize it and just passes is straight through to Angular. So, in angular.json, if you have ..., "assets": [ "src/assets" ], ..., change it to ..., "assets": [ { "glob": "**/*", "input": "src/assets", "output": "assets" } ], ....

The problem seems to be how storybook is normalizing the assets to all be object format. When a directory path is checked, storybook's isDirectory() function returns false. Since storybook doesn't think it is a directory, it seems to be trying to treat the directory as a path. By formatting the path as a file asset object, Angular still treats it as a directory, is seems, and ends up making the parent directory the output.
In node_modules/@storybook/angular/dist/server/angular-cli_utils.js I looked at the call to isDirectory() and noticed it was passing a path like /E/Git/my-ng-app/src/assets, which returned false, because fs.statSync() threw an error that the file or directory didn't exist. @angular-devkit/core exports a function to map a path to the correct system format getSystemPath(). By using getSystemPath() I got the path E:\\Git\\my-ng-app\\src\\assets, which fs.statSync() was able to find and Storybook was able to normalize it correctly.

Until fixed, using the object syntax in angular.json is probably the best workaround, since it is a valid way of defining assets. If that isn't an option for your setup, you could add an npm "postInstall" script to replace line 31 in node_modules/@storybook/angular/dist/server/angular-cli_utils.js from if (isDirectory(resolvedAssetPath)) { to if (isDirectory(core_1.getSystemPath(resolvedAssetPath))) {, but I don't recommend changing files in node_modules unless absolutely necessary.

I can probably submit a PR later with the fix mentioned above, since it is only a 2 line change, but I need to update my nodejs before I can build and test storybook locally again. If this isn't unique to Angular cli, then there may be an earlier place to convert the path to the system path, but I haven't worked back through the code that far yet.

I'm having a problem with Storybook's webpack config after beta.28
it's not including the styles I'm importing from preview.js #11304

@calebedwards21 to customize the webpack config you should check the existing loaders already configured by Storybook, sometimes you need to override them to make your rules work

Hi everyone! Seems like there hasn't been much going on in this issue lately. If there are still questions, comments, or bugs, please feel free to continue the discussion. Unfortunately, we don't have time to get to every issue. We are always open to contributions so please send us a pull request if you would like to help. Inactive issues will be closed after 30 days. Thanks!

Good golly!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.0.0-rc.15 containing PR #11472 that references this issue. Upgrade today to try it out!

You can find this prerelease on the @next NPM tag.

Closing this issue. Please re-open if you think there's still more to do.

Was this page helpful?
0 / 5 - 0 ratings