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

Keeping the path for the static directory in building #714

Closed
hansthinhle opened this issue Mar 7, 2017 · 60 comments
Closed

Keeping the path for the static directory in building #714

hansthinhle opened this issue Mar 7, 2017 · 60 comments

Comments

@hansthinhle
Copy link

In my root directory, I have a static folder names public which is served as /public/... path from my node server. That means the images and CSS files are served with that /public/ prefix.

But when I use StoryBook with the command: start-storybook -p 6006 -s ./public
The path with /public/ is no longer available.
So I changed the command to start-storybook -p 6006 -s ./ to serve the root directory, and everything is ok.

But when I build my storybook with the command build-storybook -s ./ the script will copy all files in the root directory to the storybook-static.
And if I change the command to build-storybook -s ./public, the path with /public/ prefix will not be available anymore.

Is there a way to specify the path for the static directory?

@ndelangen
Copy link
Member

Hmm so this problem is about build-storybook that's something I'd need to look into how that works.

You could give custom middleware a try?, I'm not sure it will work, but it might.
#435 (comment)
https://github.com/storybooks/react-storybook/blob/master/src/server/middleware.js#L35

@patrickgordon
Copy link

patrickgordon commented May 22, 2017

👍 This is an issue - not for building storybook but just using for dev.

Here's how I got it to work with middleware:

const express = require('express');
const path = require('path');
const paths = require("../config/paths");

const expressMiddleWare = (router) => {
	console.log(path.join(__dirname), paths.appPublic);
	router.use('/public', express.static(paths.appPublic))
};

module.exports = expressMiddleWare;

I will try to get a PR for this but not sure if I have the time atm

@ndelangen
Copy link
Member

Thank you for sharing your solution! ❤️

@stale
Copy link

stale bot commented Nov 14, 2017

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 60 days. Thanks!

@stale stale bot added the inactive label Nov 14, 2017
@stale
Copy link

stale bot commented Nov 29, 2017

Hey there, it's me again! I am going close this issue to help our maintainers focus on the current development roadmap instead. If the issue mentioned is still a concern, please open a new ticket and mention this old one. Cheers and thanks for using Storybook!

@stale stale bot closed this as completed Nov 29, 2017
@aviramga
Copy link

aviramga commented Feb 9, 2018

Hi! @ndelangen @hansthinhle @patrickgordon

Im facing the exact same issue. Was this ever solved?

Thanks!

@patrickgordon
Copy link

hi @aviramga - my solution that I posted a few up resolved it for us. I never got around doing a PR to resolve it.

Might still do that actually now that my memory has been jogged :)

@aviramga
Copy link

Hi @patrickgordon. Sadly my issue is only with build-storybook :/

I'm using it with a tool called Percy to find ui issues in my app.

Did you manage to find a solution for the build?

@Hypnosphi
Copy link
Member

Looks like you can work around this using symlinks:

Add a directory with an arbitrary name (e.g. static-link, and put there a file called public (without any extension) with following contents:

../public

Then you should be able to achieve what you need with -s static-link

@aviramga
Copy link

aviramga commented Feb 18, 2018

@Hypnosphi thanks for the tip! this doesnt seem to work though.
Can you please explain how it works?

All my static files are under a directory named "static" (not public).
I tried to ways that didn't work:

  1. Create an arbitrary directory with a file named "static" and ../static in it - cased build error when I ran build-storybook
  2. Same as a above but with a file named "public" - still don't see any images

Any advice?

Thanks

@Hypnosphi
Copy link
Member

Hypnosphi commented Feb 18, 2018

Which OS are you using?
https://en.wikipedia.org/wiki/Symbolic_link#Overview

What was the error?

@aviramga
Copy link

aviramga commented Feb 18, 2018

Mac high sierra

@Hypnosphi but just to make sure I understand correctly, to adjust your example to my use case I need to reate a new directory e.g static-link in it put a file named static and in it write ../static

Correct?

@Hypnosphi
Copy link
Member

Hypnosphi commented Feb 18, 2018

OK looks like my instruction for creating symlink was wrong. The correct way is this:

mkdir static-link
ln -s static static-link/static

It will create a "file" in static-link directory that can be shared in git (it won't work on Windows though)

@aviramga
Copy link

@Hypnosphi I will give it a shot. but does it mean I have to run it every time I ran build-storybook?

@Hypnosphi
Copy link
Member

No, it should be persistent

@aviramga
Copy link

@Hypnosphi nope, still not working. While building I get a log that says:
cp: no such file or directory: static-link/static

I followed your instructions above. So I have an empty directory called static-link with a symlink from static to static-link/static

What am I doing wrong?

Really appreciate you taking the time to help out :)

@Hypnosphi
Copy link
Member

Hypnosphi commented Feb 18, 2018

And you use -s static-link option, right?

@aviramga
Copy link

@Hypnosphi you mean build-storybook -c .storybook -s static-link ?

@Hypnosphi
Copy link
Member

Yes

@aviramga
Copy link

I do

@Hypnosphi
Copy link
Member

Sorry, I mistyped:

ln -s ../static static-link/static

@bgaynor78
Copy link

I'll add my two cents related to this issue. Though I think it's closely related, my solution differs from @mtrabelsi in that I found that simply copying my assets into the ./static directory that is a result of the build-storybook command wasn't enough. Specifically if I am deploying the static app to a Tomcat server that serves the static app from http://example.com/docs, where docs is a directory located in the Tomcat webapps/ on the server.

Because of the subpath, none of the files outside of the /css directory in the /static directory were getting loaded. I am using relative paths for images and fonts (these were the static assets that were failing to load on the deployed version). So requests like https://example.com/img/path/to/my/image failed, when it should have been adding /static, ie. https://example.com/static/img/path/to/my/image My solutions, as I said, is very close to @mtrabelsi but I just drop the two directorys if fonts and img into the root of the output:

const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = async ({ config }) => {

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

  // Other configuration properties

  config.plugins.push(
    new CopyWebpackPlugin({
      pattern: [
        {
          from: path.resolve(__dirname, './_assets'), // My static font and images are located in the .storybook dir
          to: './' // Drop both the fonts/ and img/ directory into the root of the build output.
        }
      ]
    })
  );

  return config;
}

After this, the images and fonts were loaded appropriately.

@shilman
Copy link
Member

shilman commented Jun 12, 2020

@tmeasday suggests: why can't we make this a main.js option so that it appears in both start-storybook and build-storybook

@ndelangen
Copy link
Member

@vcastro45 I've tested this for both start-storybook & build-storybook, and it seems to work (tested on the next branch).

Could you create a reproduction repo for me?

@ndelangen
Copy link
Member

@shilman It's possible, but we'd have to hoist the preset setup up from

const presets = loadPresets(presetsConfig, restOptions);

to before here:

logger.info(`=> Copying prebuild dll's..`);
shelljs.cp('-r', dllPath, path.join(outputDir, 'sb_dll'));

And then pass it down to all lower functions in the build / dev chain.
It's quite a refactor, not something I can do in 1 day.

It'd also be another moment we'd really want to migrate it all to TS. Since we'd be touching 50% of lib/core's files anyway.

@shilman
Copy link
Member

shilman commented Jun 16, 2020

@ndelangen OOF, let's not do that now then 🙈

@ndelangen
Copy link
Member

Yeah we'll do it some day

@shilman
Copy link
Member

shilman commented Jul 1, 2020

@ndelangen I've documented the workaround per discussion with @tmeasday in #11370. Propose that we move this config to main.js and add an option to support this use case in 6.x as a feature not a breaking change.

@shilman shilman removed this from the 6.0 breaking milestone Jul 1, 2020
@nfroidure
Copy link
Contributor

Do you think a solution like start-storybook -p 6006 -s "./public:/static" to serve static files from ./public on the /static path be implemented? It would lead to extremely flexible uses and fit the Docker's conventions of path mapping that lots of us are already familiar with.

@stale
Copy link

stale bot commented Aug 16, 2020

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!

@stale stale bot added the inactive label Aug 16, 2020
@ndelangen
Copy link
Member

@nfroidure that is an interesting idea for sure!

@nfroidure
Copy link
Contributor

@ndelangen I can give a try to it with a PR if you wish. Any chance it gets merged?

@stale stale bot removed the inactive label Aug 20, 2020
@ndelangen
Copy link
Member

@nfroidure would be doable:
Here is where the code would go:

const staticPath = path.resolve(dir);
if (await !fs.exists(staticPath)) {
logger.error(`Error: no such directory to load static files: ${staticPath}`);
process.exit(-1);
}
logger.info(`=> Loading static files from: ${staticPath} .`);
app.use(express.static(staticPath, { index: false }));
const faviconPath = path.resolve(staticPath, 'favicon.ico');
if (await fs.exists(faviconPath)) {
hasCustomFavicon = true;
app.use(favicon(faviconPath));
}
})

@nfroidure
Copy link
Contributor

Well I have something here : #12222

Some tests are failing but I cannot see any link between those failures and my changes.

LMKWYT ;)

@ndelangen
Copy link
Member

Thank you for this PR @nfroidure !

I'll look at it this week!

@shilman
Copy link
Member

shilman commented Sep 10, 2020

ZOMG!! I just released https://github.com/storybookjs/storybook/releases/tag/v6.1.0-alpha.6 containing PR #12222 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.

@shilman shilman closed this as completed Sep 10, 2020
@SpicyPete
Copy link

Is there an example of how to use this new feature?

@iaremarkus
Copy link

Fun fact I stumbled on today, that might be related to the above:

npm run build-storybook -s ./src,./public
does NOT copy those folders into storybook-static

yarn build-storybook -s ./src,./public
does

🤷

@RoamingAnt
Copy link

RoamingAnt commented Feb 10, 2021

For anyone wondering how to use the feature for mapping the static file directory that was added in #12222. You can map the local path to a remote one using the CLI parameter like so -s <local path>:<remote path>

As an example, taking the original question it would work like so:
start-storybook -p 6006 -s ./public:/public

@Sid-Turner-Ellis
Copy link

Sid-Turner-Ellis commented Oct 31, 2022

None of the images were loading within my pipeline but worked fine locally, ended up being because the components were fetching images using a relative path <img src="/my-image" /> which apparently is not allowed using the file protocol.

I ended up doing 2 things:

  1. Updating the static dirs directory to use the root by updating the main.js file in storybook
module.exports = {
 staticDirs: [{ from: '../static', to: '/' }],
}
  1. Added a script to remove the leading slash of images in the preview-head.html file from storybook
<script>
  document.addEventListener('DOMContentLoaded', () => {
      Array.from(document.querySelectorAll('img')).forEach((img) => {
        const original = img.getAttribute('src');
        img.setAttribute('src', original.replace('/', ''));
      });
  });
</script>

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