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

Windows staticDirs issue - Storybook not loading assets despite path seemingly correct #17271

Closed
LaurenceCliff opened this issue Jan 18, 2022 · 30 comments

Comments

@LaurenceCliff
Copy link

LaurenceCliff commented Jan 18, 2022

Describe the bug
On a Windows machine the staticDirs build with the expected structure:

dist/
    storybook/
        assets/
            imgs/
                imgs_sub/
                    image.png
            svgs/
                icon.svg

Then when we run npm run start, Storybook starts and appears to be working fine, but none of the static assets can be found. When looking at the network it seems to be requesting the correct paths:

http://localhost:6006/assets/imgs/imgs_sub/image.png
http://localhost:6006/assets/svgs/icon.svg

But it's returning a 404. If I go direct to that path it also doesn't load.

main.js looks like this:

module.exports = {
  stories: ['../src/**/*.stories.ts'],
  addons: ['@storybook/addon-actions', '@storybook/addon-links', '@storybook/addon-a11y', '@storybook/addon-knobs'],
  staticDirs: [
    '../src/assets',
    { from: '../projects/icons/svgs', to: './assets/svgs' },
    { from: '../projects/images', to: './assets/imgs' }
  ],
  core: {
    builder: 'webpack5'
  },
  angularOptions: {
    enableIvy: false
  }
};

Debugging server-statics.js returns the following:

_arg$split = [".\projects\icons\svgs",".\assets\svgs"]
target=".\assets\svgs"
staticDir="./.\projects\icons\svgs"
staticPath="C:\Users\user\IdeaProjects\repo\projects\icons\svgs"
targetDir="./.\assets\svgs"
targetEndpoint="/.\assets\svgs"

and for imgs

_arg$split = [".\projects\images",".\assets\imgs"]
target=".\assets\imgs"
staticDir="./.\projects\images"
staticPath="C:\Users\user\IdeaProjects\repo\projects\images"
targetDir="./.\assets\imgs"
targetEndpoint="/.\assets\imgs"

If I remove the dot from main.js, like so, then the build errors:

staticDirs: [
    '../src/assets',
    { from: '../projects/icons/svgs', to: '/assets/svgs' },
    { from: '../projects/images', to: '/assets/imgs' }
],

Error returned:

info => Copying static files: C:\Users\user\IdeaProjects\repo\src\assets at C:\Users\user\IdeaProjects\repo\dist\storybook\
C:\Users\user\IdeaProjects\repo\node_modules\@storybook\core-server\dist\cjs\utils\server-statics.js:118
    throw new Error((0, _tsDedent.default)((0, _chalk.default)`
          ^

Error: Failed to load static files, no such directory: C:\Users\user\IdeaProjects\repo\projects\icons\svgs:\assets\svgs

System

Environment Info:

  System:
    OS: Windows 10 10.0.19044
    CPU: (8) x64 Intel(R) Core(TM) i7-8565U CPU @ 1.80GHz
  Binaries:
    Node: 16.13.2 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.17 - ~\IdeaProjects\repo\node_modules\.bin\yarn.CMD
    npm: 6.14.15 - ~\IdeaProjects\repo\node_modules\.bin\npm.CMD
  Browsers:
    Chrome: 97.0.4692.71
    Edge: Spartan (44.19041.1266.0), Chromium (97.0.1072.62)
  npmPackages:
    @storybook/addon-a11y: ^6.4.13 => 6.4.13
    @storybook/addon-actions: ^6.4.13 => 6.4.13
    @storybook/addon-knobs: 6.2.9 => 6.2.9
    @storybook/addon-links: ^6.4.13 => 6.4.13
    @storybook/addons: ^6.4.13 => 6.4.13
    @storybook/angular: ^6.4.13 => 6.4.13
    @storybook/builder-webpack5: ^6.4.13 => 6.4.13
    @storybook/manager-webpack5: ^6.4.13 => 6.4.13
@shilman
Copy link
Member

shilman commented Jan 26, 2022

@kroeder can you please look into this? i think you're doing this successfully on your project

@HIMISOCOOL
Copy link

any updates? its pretty annoying to have to manually import all my assets from static.

@youngchon
Copy link

I just ran into this recently, staticDir:[..] instead of staticDirs:[...]

@LaurenceCliff
Copy link
Author

I just ran into this recently, staticDir:[..] instead of staticDirs:[...]

Hi, I've just tried this with staticDir instead of staticDirs and it doesn't output the assets at all that way so I suspect it's something else that's not right.

@ambroiseRabier
Copy link

It might sound dumb, but for me, I just realized I am using version 6.2, and 6.2 doesn't have staticDirs feature, I have to use start-storybook -s ./static instead.

@HIMISOCOOL
Copy link

It might sound dumb, but for me, I just realized I am using version 6.2, and 6.2 doesn't have staticDirs feature, I have to use start-storybook -s ./static instead.

thats fair, Im using 6.4 which has OP's issue though

@LaurenceCliff
Copy link
Author

Hi @kroeder, just wondering if there's any update on this, is it looking like an incorrect config on my side or is something not right with Storybook? Keen not to have to revert back to an older version. Thanks

@dutscher
Copy link

dutscher commented Feb 22, 2022

the same for me.
i wanted to remove the deprecation warning DeprecationWarning: --static-dir CLI flag is deprecated and i start to migrate to the staticDirs in main.js.

At first i tried the simple config:

module.exports = {
  ...
  staticDirs: ['../assets'],
};

but this means all dir will flatten.
but dont want flatten dirs. then i changed to staticDirs: [{ from: '../assets', to: '/assets' }];
and now i got the same as @LaurenceCliff: my dirs are not exists, but there existing and working with the simple flatten config.
im also work on windows 10.

cheers


 C:\...\node_modules\@storybook\core-server\dist\cjs\utils\server-statics.js:128
throw new Error((0, _tsDedent.default)((0, _chalk.default)`
          ^

Error: Failed to load static files, no such directory: C:\...\packages\base\assets:\assets
Make sure this directory exists, or omit the -s (--static-dir) option.
    at parseStaticDir (C:\...\node_modules\@storybook\core-server\dist\cjs\utils\server-statics.js:128:11)
    at async C:\...\node_modules\@storybook\core-server\dist\cjs\utils\copy-all-static-files.js:62:34

@JeanMeche
Copy link

Can confirm, broken on windows, works on WSL Ubuntu.

my config:
staticDirs: [{ from: '../icons', to: '/ngx-ui/icons' }],

Same problem as OP, no such directory: XXXXXXXX\dev\ngx-ui\icons:\ngx-ui\icons

as you can see, the path duplicated the /ngx-ui/icon part but also inserts a colon.

@dutscher
Copy link

the colon is a seperator for "src":"destination" ;)

i promise the backslashes are the main problem.
it should do a simple const osSafePath = path.replace(/\\/g, '/');

cheers

@JeanMeche
Copy link

Are you sure about that ?
Here, it seems staticPath is only a path.

@justrhysism
Copy link
Contributor

This might have something to do with it:

image

The regex for the split isn't strict enough.

@justrhysism
Copy link
Contributor

justrhysism commented Mar 7, 2022

👆🏼 So I fixed this and submitted a PR, details are (copied from PR):


Noticed that the test "supports absolute file paths with custom endpoint" didn't cover the reality for Windows.

The relativeDir provided by getDirectoryFromWorkingDir() resolves all paths to OS separators (e.g. \ on Windows). The result of which would look like C:\\foo\\bar:\\custom-endpoint and not C:\\foo\\bar:/custom-endpoint which the test was covering; so I added a test to cover the actual case.


Digging in, the regex split in parseStaticDir didn't account for the actual path, as it was ignoring all cases of :\ to cover the X:\ scenario, which is what resulted in bug #17271.

To work around this, I changed the code to look for the last colon :, and use that to split. However, in case the last colon is actually part of a Windows absolute path (e.g. C:\), needed to check a few conditions:

  • Is the path Windows absolute? (We don't care if Unix absolute because it won't have a colon)
  • Is the path just a single path (i.e. doesn't contain the : delimiter for static and target dirs.

Once this was determined, the final piece of the puzzle was ensuring the target was converted from \ to /, for which I just split on path.sep and joined on path.posix.sep to ensure a forward-slash /.

@shilman shilman closed this as completed in 6f9c8a5 Mar 9, 2022
@shilman
Copy link
Member

shilman commented Mar 9, 2022

Whoopee!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.5.0-alpha.47 containing PR #17641 that references this issue. Upgrade today to the @next NPM tag to try it out!

npx sb upgrade --prerelease

@maximedaoust
Copy link

maximedaoust commented Mar 23, 2022

Sorry to jump in a closed issue, but is this problem also linked to the fact that I am not able to use the following ?

    staticDirs: [
      { from: '../../public', to: 'assets/' }, // working properly
      { from: '../../public', to: '/assets' }, // not working
      { from: '../../public', to: '/assets/' }, // not working
    ],

Based on a docs configuration object example found here, it should work with a leading foward slash.

@JoshSchreuder
Copy link

JoshSchreuder commented Apr 20, 2022

Would be nice to backport this to 6.4.x if it's not too much trouble 😄

@JoaquimCAP
Copy link

I got stuck because of this bug and I can't upgrade to another version...
But I found a workaround that allows me to continue:

You can also configure a directory (or a list of directories) for searching static content when you are starting Storybook. You can do that with the -s flag.
https://stackoverflow.com/questions/58267903/serving-static-files-in-storybook-js

Thanks for your great work and all the best for the Storybook team!

@femi-ojemuyiwa-aa
Copy link

Still doesn't work

@D-Thrane
Copy link

Did anyone get this to work? I have a folder in the root called public with a svg folder inside. The svg folder ends up in the root of storybook-static. I need it to put the svg folder inside a folder called public.

@Tokimon
Copy link

Tokimon commented Dec 15, 2022

I have experienced this as well. For me/us it is a problem with copying favicon.ico. But it is totally random and only shows up once every 10 builds on local, but every time in our docker build.
image

We are using version 6.5.14

@D-Thrane
Copy link

I also on 6.5.17

Did add this in main.js but it does nothing.

  "staticDir": [
    { from: './public/', to: 'public/' },
  ],

@jndietz
Copy link

jndietz commented Dec 15, 2022

Yep - experiencing this issue as well with 6.5.14.

// preview.js
import Theme from "../src/components/Theme/Theme";
import { ColorConfig } from "@company/company-ui";

import "../assets/fonts.css";   // 👈 fonts are in here
import "../assets/global.css";
import "../assets/test.css";

export const decorators = [
  (Story) => (
    <Theme>
      <ColorConfig mainColor="rgb(91, 121, 139)" />
      <Story />
    </Theme>
  ),
];

export const parameters = {
  actions: { argTypesRegex: "^on[A-Z].*" },
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
  },
};
// main.js
module.exports = {
  stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
  addons: [
    "@storybook/addon-links",
    "@storybook/addon-essentials",
    "@storybook/addon-interactions",
  ],
  framework: "@storybook/react",
  "core": {
    "builder": "@storybook/builder-webpack5"
  },
  staticDirs: ["../assets"],
};
info @storybook/react v6.5.14
info 
info => Loading presets
info => Serving static files from ./.\assets at / 👈 assets appear to be loaded in, but I don't see them loading in the browser
info => Loading custom babel config as JS
info => Loading custom babel config

It should be loading a Roboto font, but it doesn't load, so the browser is falling back to Times New Roman.

image

Further inspection reveals that my assets folder is located under the .. Is this right?

image

MVCE
https://github.com/jndietz/storybook-6-5-14-static-asset-issue-17271

@Tokimon
Copy link

Tokimon commented Dec 16, 2022

I have experienced this as well. For me/us it is a problem with copying favicon.ico. But it is totally random and only shows up once every 10 builds on local, but every time in our docker build. image

We are using version 6.5.14

So we found a solution in our case, which was a mixture of a couple of things

  1. We updated Node and pnpm to latest just to be sure.
  2. in our solution we copy the file from the application and from storybook into the same folder (/public), which meant that we had favicon.ico twice and it seems that storybook fails because it tries to write the favicon file to a path that already has a one. This is not clear from the error message, though, but renaming our main favicon to something else, seems to fix the issue.

So in short, in our case it seems to be a problem with files with the same name in the destination folder.

@ravish-goel
Copy link

This is not working with 6.5

main.js config => staticDirs: ['../public'],

This is the logo (in public folder). Check the storybook log at the bottom. It is able to find the directory.
img1

This is how it is displayed.
img2

This is how it comes
img3

@Mrblackey
Copy link

I confirm that this is still an issue in 6.5.16. :(

@SherAtrium
Copy link

The same issue in 6.5.13

@Mrblackey
Copy link

Update:
Problem solved for me after creating storybook-static folder at the root of my project and placing all the assets files there.

@SeanMcMillan
Copy link

Ran into this. It seems that having '..' in the path breaks somewhere in the path normalization chain.

I had staticDirs: [{ from: '../src/stories/assets', to: '/assets' }],, and it failed to serve the directory, but when I switched to staticDirs: [{ from: './assets', to: '/assets' }], (and moved the files), it worked.

@jaandrews
Copy link

jaandrews commented Jul 31, 2024

I'm running into this as well with version 8.2.6 of storybook, but I can't reorganize the files like SeanMcMillan suggests, as it's tied to a nextjs project that requires the current folder structure. My problem is that they handle the public folder differently.

In nextjs, files in the public directory are treated as if they are in the root of the project, so a font would be loaded with

   @font-face {
       font-family: "ExampleFont";
       src: url("/fonts/ExampleFont.otf") format("opentype")
   }

To get it to load in storybook, I have to include "/public" in the url, even though I've set up a static directory to map the "../public/fonts" to "/fonts"

   @font-face {
       font-family: "ExampleFont";
       src: url("/public/fonts/ExampleFont.otf") format("opentype")
   }

The strange thing is that the path without "public" does work when I visit the site on the front end before it throws the error, but that might be due to it running the "@storybook/nextjs" framework, which might be doing something for the front end that isn't factored into the build process.

@jaandrews
Copy link

Found a different open issue #19340 that refers specifically to the problem I mentioned above.

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

No branches or pull requests