-
-
Notifications
You must be signed in to change notification settings - Fork 9.3k
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
NextJS: Fix Image Context reuse (ensure singleton by externalizing it) #23881
NextJS: Fix Image Context reuse (ensure singleton by externalizing it) #23881
Conversation
52961b7
to
6b00ed9
Compare
I understand now. The issue I have is that: storybook/code/frameworks/nextjs/package.json Lines 151 to 152 in ba0e4e2
represents these: storybook/code/frameworks/nextjs/package.json Lines 143 to 144 in ba0e4e2
But this is not obvious, and it's very fragile to externalize relative paths like that. When importing something that's externalized, we can make this very clear: - import { ImageContext } from './context';
+ import { ImageContext } from '@storybook/nextjs/dist/image/context'; If we do that, there's no relative path to externalize. storybook/scripts/prepare/bundle.ts Lines 61 to 66 in ba0e4e2
Importing this way does mean we have to add it to the export map in storybook/code/frameworks/nextjs/package.json Lines 23 to 43 in ba0e4e2
..or vite will complain.
As a general aim, I'd like to have bundler-entries be at the top-level in the So the preferred way would be: import { ImageContext } from '@storybook/nextjs/dist/image-context'; |
ba0e4e2
to
f4a1021
Compare
Thank you for the thorough explanation! I think I've made the correct changes but now I'm getting this error: Should I just add |
…/storybook into pr/martinnabhan/23881
What I did
I'm not exactly sure when but between #21909 being merged and it being released props specified in
parameters.nextjs.image
have stopped being applied tonext/image
.After some debugging it turns out that the React Context (
ImageContext
) being used to pass the props fromparameters.nextjs.image
tonext/image
isn't being reused, instead it's recreated in every file where it's imported. This happens because webpack inlines the contents ofcontext.ts
instead of keeping the import statement intact.Since we want to reuse the same context everywhere we should make sure webpack preserves the import even after building, which can be done by marking
context.ts
as an external file that shouldn't be included in the output bundle.Note we also need to mark
decorator.tsx
as external, or else it will be included in thepreview.js
bundle, causing the import ofcontext.ts
to fail.How to test
If you look at the current output you can see
ImageContext
being recreated in every file it's imported.For example in
dist/preview.js
,dist/images/next-image.js
ordist/images/next-legacy-image.js
you will see the following line:After building this branch the output instead turns into
for
preview.js
andfor
decorator.js
and finallyfor
next-image.js
,next-legacy-image.js
, andnext-future-image.js
, which means the context is correctly being reused instead of recreated.Checklist
MIGRATION.MD
Maintainers
ci:normal
,ci:merged
orci:daily
GH label to it to run a specific set of sandboxes. The particular set of sandboxes can be found incode/lib/cli/src/sandbox-templates.ts
["cleanup", "BREAKING CHANGE", "feature request", "bug", "build", "documentation", "maintenance", "dependencies", "other"]