Closed mnquintana closed 1 year ago
Was this working as expected in a previous version of Storybook?
It was! It was working as expected in 6.1.21.
Do you have a repro repo you can share?
Sure!
From some additional testing, it seems like this is only broken with the Webpack 5 builder after all. This is the culprit: https://github.com/mnquintana/storybook-font-preload-repro/blob/storybook%406.2-webpack5-minimal-repro/styles/global.css#L4-L6
Something changed with how paths are resolved in CSS files in the Webpack 5 builder. When I tried using the original paths from Storybook 6.1, Webpack threw this error:
ModuleBuildError: Module build failed (from ./node_modules/@storybook/builder-webpack5/node_modules/css-loader/dist/cjs.js):
Error: Can't resolve '/assets/fonts/Inter.woff2' in '/Users/mnquintana/code/storybook-font-preload-repro/styles'
at finishWithoutResolve (/Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/enhanced-resolve/lib/Resolver.js:293:18)
at /Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/enhanced-resolve/lib/Resolver.js:362:15
at /Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/enhanced-resolve/lib/Resolver.js:410:5
at eval (eval at create (/Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:16:1)
at /Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/enhanced-resolve/lib/Resolver.js:410:5
at eval (eval at create (/Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:27:1)
at /Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/enhanced-resolve/lib/DescriptionFilePlugin.js:87:43
at /Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/enhanced-resolve/lib/Resolver.js:410:5
at eval (eval at create (/Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:16:1)
at /Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/enhanced-resolve/lib/forEachBail.js:16:12
at /Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/enhanced-resolve/lib/AliasPlugin.js:103:14
at next (/Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/enhanced-resolve/lib/forEachBail.js:14:3)
at forEachBail (/Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/enhanced-resolve/lib/forEachBail.js:24:9)
at /Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/enhanced-resolve/lib/AliasPlugin.js:37:5
at _next0 (eval at create (/Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:8:1)
at eval (eval at create (/Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:30:1)
at processResult (/Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/webpack/lib/NormalModule.js:676:19)
at /Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/webpack/lib/NormalModule.js:778:5
at /Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/loader-runner/lib/LoaderRunner.js:399:11
at /Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/loader-runner/lib/LoaderRunner.js:251:18
at context.callback (/Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/loader-runner/lib/LoaderRunner.js:124:13)
at Object.loader (/Users/mnquintana/code/storybook-font-preload-repro/node_modules/@storybook/builder-webpack5/node_modules/css-loader/dist/index.js:154:5)
at runMicrotasks (<anonymous>)
at processTicksAndRejections (node:internal/process/task_queues:94:5)
That same path resolves as expected with the Webpack 4 builder on Storybook 6.2.8.
I had to change that path in global.css
to the relative path on disk for Webpack to resolve the path properly, but then it broke font preloading in production builds because Webpack 5 resolves that path to one that includes a hash in the filename, which can't be referenced from within preview-head.html
.
@mnquintana so it works with webpack4 in 6.2?
@mnquintana so it works with webpack4 in 6.2?
It does! Let me know if there's any more info I could provide that'd be helpful for debugging.
Thanks so much for all the info, this is wonderful 🙏
found any workaround in the meantime that doesn't involve changing versions ? I'm using 6.3.8 in storybook react.
I had the same issue.
My Fonts are in src/fonts/ and are included in my stylesheet via scss imports, thus emitted by webpack as an asset. For preloading to work the font definition in the css must use the same url as the tag in the head – using storybooks static file serving isn't an option in that case.
The default webpack configuration used by storybook generates different filenames depending on the production flag (which is probably when you run storybook dynamically and true when you build it). https://github.com/storybookjs/storybook/blob/64122cb5201b5a0473fdc079726610cf39c04ad4/lib/builder-webpack5/src/preview/base-webpack.config.ts#L54-L62
So if you add one url to your preview-head.html it will only work in one mode and not the other.
The workaround is to simply preload both urls and live with the 404 error
e.g.
<!-- Font Preloading in dynamic mode -->
<link rel="preload" as="font" type="font/woff2" href="/static/media/src/fonts/5262913/8a7eda06-48ab-4713-bddd-338da4dc23bd..woff2" crossorigin>
<!-- Font Preloading in built -->
<link rel="preload" as="font" type="font/woff2" href="/static/media/8a7eda06-48ab-4713-bddd-338da4dc23bd.a52b710f..woff2" crossorigin>
Alternative workaround:
Use the webpackFinal option and change the rule mentioned above to use the same filename in both modes.
For a proper fix we would need access to the generated filename in preview-head.html or in the previewHead option.
Or integrate a webpack plugin like https://www.npmjs.com/package/webpack-font-preload-plugin to change the header?
We’re cleaning house! Storybook has changed a lot since this issue was created and we don’t know if it’s still valid. Please open a new issue referencing this one if:
Describe the bug
It seems that preloading fonts from a local static directory in
.storybook/preview-head.html
is broken as of Storybook 6.2. This is reproducible both with the ~default Webpack 4 and~ new Webpack 5 builder. It's not reproducible in Storybook 6.1.x, or on Storybook 6.2.x with Webpack 4.Example
preview-head.html
For a file located at
/public/Inter.woff2
, and with Storybook run with./public
as a--static-dir
:There's a workaround for the bug in development builds (change the URL to start with
/static/media/public/
), but production builds additionally don't work because Storybook inserts a hash in the filename now (see repro steps below).Let me know if there's any other info I could provide that'd be helpful for debugging!
To Reproduce
Minimal Repro Repo
Prerequisites
/public/<font>.woff2
)start-storybook --static-dir ./public
andbuild-storybook --static-dir ./public
).storybook/preview-head.html
and it includes this<link>
:/styles/global.css
):@storybook/builder-webpack5
and have{ core: { builder: 'webpack5' } }
set in your.storybook/main.js
Production
build-storybook --static-dir ./public
Expected
<font>.woff2
is successfully preloaded from/<font>.woff2
.Actual
<font>.woff2
is not successfully preloaded from/<font>.woff2
because the CSS file fetches from a different path –/<font>.<hash>.woff2
./Inter.ce6ee6f8.woff2
System
Please paste the results of
npx sb@next info
here.┆Issue is synchronized with this Asana task by Unito