-
-
Notifications
You must be signed in to change notification settings - Fork 9.2k
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
Is there a lifecycle module that's called before each story in a browser only? #11378
Comments
@yannbf i think you looked at this? I think the most reliable way to hook in before a story render is to add a global decorator, but not sure if that suits your use case... |
Hey @kettanaito, Nice to see that you're working on this! As of now I'd say unfortunately it's necessary to add a few workarounds to use msw with storybook, indeed preview is the way to go for registering the service worker, and a decorate to check if the story can be rendered. But if I'm not mistaken there are people working on making stories async (@tmeasday can explain that better I think) and once that is done, integrating msw will be easier! |
Thank you for the quick replies, folks. Do you find this approach sensible? // .storybook/preview.js
// Storybook executes this module in both bootstap phase (Node)
// and a story's runtime (browser). However, cannot call `setupWorker`
// in Node environment, so need to check if we're in a browser.
if (typeof global.process === 'undefined') {
const { worker } = require('../src/mocks')
// Start the mocking when each story is loaded.
// Repetitive calls to the `.start()` method do not register a new worker,
// but check whether there's an existing once, reusing it, if so.
worker.start()
} |
@kettanaito I have had an issue with this, mainly that stuff is getting 500'ed by msw (like fonts, one works one doesn't, race condition?). Only happens in storybook. My setup has the addDecorator(storyFn => {
if (process.env.NODE_ENV === 'development') {
const { worker } = require('../src/mocks/browser');
worker.start();
}
return <SomeProviders>{storyFn()}</SomeProviders>
}); Only issue I can see is that navigating between stories outputs a fresh |
In fact, I seemed to fix that with: const worker = process.env.NODE_ENV === 'development' ? require('../src/mocks/browser').worker : null;
let workerRun = false;
addDecorator(storyFn => {
if (!workerRun && worker) {
workerRun = true;
worker.start();
}
return <SomeProviders >{storyFn()}</SomeProviders>
}); |
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! |
@simmo, if you update to the latest version of MSW (0.20.x), some of the previously described issued may be fixed. We've added improvements to the worker instance management. I'd love to hear your feedback on this. |
We've added some docs in the 6.0 release that are probably relevant to this issue: https://storybook.js.org/docs/react/workflows/build-pages-with-storybook |
Thanks @kettanaito + @tmeasday . Looks good, I think MSW 0.20+SB 6 updates are helping but worker init (well, console log at least) is still output multiple times. Looking at updated Storybook docs, a decorator might not be the best solution for implementing it. I'm going to have a play! 😄 |
If you figure out some useful information feel free to PR the docs, it is all pretty new + raw at this stage. Also you might want to look at what they are doing over at Redwood; they have a msw+SB integration going there. |
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! |
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! |
Thanks, @tmeasday. I've got some time to look into this, and I really like the This is what I used to do in // .storybook/preview.js
// Storybook executes this module in both bootstap phase (Node)
// and a story's runtime (browser). However, cannot call `setupWorker`
// in Node environment, so need to check if we're in a browser.
if (typeof global.process === 'undefined') {
const { worker } = require('../src/mocks/browser')
worker.start()
} As mentioned before, this does work but is not quite developer-friendly to advocate. If I swap this with a global decorator, it gets executed before each story: // .storybook/preview.js
export const decorators = [
(Story) => {
const { worker } = require('../src/mocks/browser')
// As this decorator gets called before each story,
// MSW registers and activates repeatedly.
worker.start()
return <Story />
}
] While there is a deduplication mechanism on MSW's side and calling And so the search for the right approach continues. I'll reach out to Redwood developers to see how they are integrating MSW. |
Hey @kettanaito, I'm not sure a decorator is really necessary if this only needs to happen once. I would have thought just calling code directly in |
Hey, @tmeasday. Thanks for the suggestions. SInce I'm currently facing another issue: the // stories/User.story.js
// This `import` is called in both NodeJS and in a browser,
// raising an error since the worker isn't meant for NodeJS.
import { worker } from '../mocks/browser'
const Story = () => <User />
Story.decorators = [
(Story) => {
worker.use(/* runtime handler */)
return <Story />
}
] Now, in order for the example above to work, I need to conditionally export the worker, omitting the export in a NodeJS environment: // mocks/browser.js
export const worker =
typeof global.process === 'undefined' && setupWorker(...handlers) |
Hey @kettanaito I'm not sure what you mean when you say "during Storybook build" -- I wonder if you mean inside storyshots or something? |
Hi, @tmeasday. Forgive me for some of the misleading terminologies. When I try to run Storybook there seems to be no issue, it must have been some quirks on my setup's side. Let me investigate it further and come back with the updates. Thanks. |
Hey 👋 Thanks for an awesome project! I've been using Storybook for years and I love it.
I'm maintaining a usage example of Mock Service Worker library with Storybook, and I have a question about the best way to integrate those two.
Integration
The point of the integration is to call the
setupWorker
function before each story in a browser.setupWorker
cannot be called in a Node environment (that includes DOM-like environments like jsdom).Current behavior
I'm placing my logic into
.storybook/preview.js
, which is promised to run before each story. While it does do so in a browser, it's also run in Node when I test my stories.You can verify that by checking out the examples repository mentioned below, and running the following command:
$ yarn test
Expected behavior
Is there a configuration module that's executed before each story, but only in a browser environment?
Reproduction repository
Please refer to the Storybook usage example repository to play around with this setup by yourself. I'd be thankful for any guidance and suggestion in this. Exciting to bring an awesome example of a usage with Storybook!
The text was updated successfully, but these errors were encountered: