-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
Compile addons/lib in both CJS/ESM + Enable lazy loading for some larger components #12406
Conversation
@hipstersmoothie you are a superhero for taking this on, and this PR is epic 🤯 any chance you can get the build passing while we review? |
@shilman this is as ready as I can get it without some guidance |
Amazing @hipstersmoothie. I'll try to make sense of all this today with @ndelangen when he comes online |
OK, I took a look with @ndelangen and we're both thrilled about this PR. CI. The build error in Chromatic is due to IE11 compat breaking. Apparently the generated bundle has arrow functions:
Perf I'm building out benchmarks for Storybook and the benchmark values are really bad on Review The PR is too big to review in its current form. What I propose is let's get the build working and the perf numbers, and then once we're happy, split it into two PRs (yes, I know 😅 🔫 ), one for the ESM stuff and the second for lazy loading. WDYT? |
I can do that I but the lazy loading pr will only be like 6 files so it's not gonna make the burden of review to much smaller Edit: I lied. The lazy loading touches 10 files 😅 the main problem is that to get tree shaking working at all I needed to changes the builds for every package that uses the thing we want tree shaken. So if anything is using a component in from cjs compiled files, everything gets included and no tree shaking happens. |
Ok hold off on splitting then. Let's discuss again after i get the perf stuff in hand |
@hipstersmoothie I merged a higher-performing BTW, the new commit structure is 💯 . looks like something we can review! |
@shilman this PR actually fixes a lot of the issues that were fixed in that higher performing branch. The following pattern is quite abundant in the storybook code:
Problems:
Benfits:
By adding and ESM build to all of the packages and addons this fixes this problem. Since the ESM packages can actually be tree shaken now, perf regressions like the one you just fixed never have to happen. With that we can stop adding these extra root files and really depend on webpack to do its magic. With ESM enabled we can now:
And now all of our problems get fixed:
And we still get
But some problems do arise:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I'm still wrapping my head around all this, so thank you for all the clarifications. This is tremendous work and I appreciate it even more as I dig in.
Here are some initial comments for discussion (cc @tmeasday @ndelangen @ghengeveld):
-
AFAICT this is a breaking change, since it is getting rid of the non-root entry points of the packages (e.g.
@storybook/addon-docs/blocks
). I'm not 100% against breaking changes (perf is top priority and I'm happy to release 7.0 if we can make a step change in perf). -
Is it possible that we get rid of CJS entirely if this is already a breaking change? There are only a few cases where we need CJS as I understand it (code required by the presets)
-
There are some addon-docs README files deleted in this PR, and we'll need to move that content somewhere. I can take care of this with @jonniebigodes, but just want to make note of it here before we merge this.
-
Do we need to instruct third party addons to compile this way, or is it fully backwards compatible? What about stuff outside of lib/addons? Follow-on work for further optimization?
-
There is some special case code for
virtualModuleEntry.template.js
but none forvirtualModuleStory
orvirtualModuleRef
. Should there be?
Apologies in advance if these are stupid questions!
And these are great questions! |
Ok, I've also created a benchmark to track performance across PRs. I'll be documenting this more soon, but basically it's installing and running It's not very user-friendly yet, but you can click on the "branch" drop-down to isolate different branches. Here's what it looks like for this PR: |
That's useful. Does it update as a push? |
Also could I see where this code that generates the benchmark is? I think that I might need to tweak the webpack mode for this |
The benchmark code is here: https://github.com/storybookjs/bench The runner is here: https://github.com/storybookjs/storybook/blob/next/scripts/run-e2e-config.ts#L200-L209 It runs as part of our e2e tests on every push. Feedback welcome on any of this. I plan to add another benchmark for a loaded Storybook, possibly |
Updates
With a CJS virtual module template: with an esm virtual module template: |
not sure why these particular metrics are so bad. Does this graph take the latest build? I know I just pushed commits that reduce the time. It would be super nice to be able to run the benchmark locally for testing. Not really sure how. I compared the startup time of the react-ts example and the changes in startup time was negligible |
@hipstersmoothie running the benchmark locally is easy: yarn create react-app cra-bench
cd cra-bench
npx @storybook/bench 'npx sb init' this will dump the results in unfortunately, it uses the latest version of storybook and not your local branch. to do that in CI we use verdaccio. i believe you can do this in the storybook repo:
I haven't verified the registry part, but you can see the code here https://github.com/storybookjs/storybook/blob/next/.circleci/config.yml#L108-L137 |
I've set the "data freshness" in Google Data Studio to 15 minutes. That means that the data should be visible on the report about 45 minutes after you push a commit--not great, but it's what we've got for now. I've updated the report to make it a little more user friendly. If you work in the Storybook repo (not a fork) and you have a branch called |
LMK if you have any reporting requests. happy to modify/add pages, or can give you write access to the report if you'd like to edit that. Also feel free to jump on our discord if you'd like to chat in realtime: https://discord.gg/UUt2PJb |
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! |
This was extended and merged in #13013. Closing for now. Thank you @hipstersmoothie for helping get Storybook onto ESM! |
Issue: adresses some of #9290 (polyfills still included), #9282
What I did
The bundle size for included dependencies in a storybook website can get quite large. This PR lays the groundwork to incrementally improve the state of tree-shaking and lazy-loading in storybook's output.
This PR main focuses on:
addons
andlib
package into bothCJS
andESM
versionsColorControl
,react-syntax-highlighter
,tooltip
)Addon Changes
The biggest hurdle in making this work was getting the addons to work.
Currently an addon package is a mix of two types of code:
node
that builds thestorybook
webpack configs (preset
andregister
code)Since the addon
dist/
folder now has two sub-folders (cjs
andesm
). Defining thepreset
code insrc
led to hard pathing problems. To mitigate this I chose to move all of the preset code straight into the rootpreset.js
file. From this file you can still access compiled utils indist/cjs
, but allentries
and other files loaded into storybook are fromdist/esm
.This is not a breaking change to the API, just a better way to structure storybook's addon code.
Upgrade Babel + TypeScript
Exporting
ESM
code exposed a lot of places in code where we were explicitly exporting a type or interface. To fix this I change those toexport type
statements. This required upgrading to[email protected]
and[email protected]
.Is this a breaking change?
This does not break an APIs but it does break direct import from
dist
(ex:@storybook/links/dist/react
). Whether this breaks APIs is up to the maintainers 😄 . In some of these cases I just chose to include whatever was being imported to the index file. This is both better for knowing what the public api is and is simpler for the user.Possible Further Improvements
register.js
files as they break tree-shakenResults
examples/react-ts
before:examples/react-ts
after:How to test
If your answer is yes to any of these, please make sure to include it in your PR.