Storyshots不遵守视口宽度配置:指定自定义视口仍以1024px渲染组件
问题原因说明
这不是已知Bug,属于配置遗漏问题。Storybook官方的viewport插件的参数默认仅作用于Storybook的可视化预览界面,不会自动同步到Storyshots的Jest/jsdom测试环境,默认jsdom的视口宽度就是1024px,所以会出现你遇到的情况。
修复方案
你需要改造Storyshots的测试逻辑,在渲染每个story前主动读取viewport配置,修改jsdom的视口参数,示例配置如下:
import { initStoryshots, multiSnapshotWithOptions } from '@storybook/addon-storyshots'; import { Stories2SnapsConverter } from '@storybook/addon-storyshots'; // 导入你定义的所有视口配置 import { allViewports } from './your-viewport-config-path'; const customSnapshotTest = async ({ story, context }) => { // 读取当前story的viewport参数 const viewportParams = story.parameters?.viewport; if (viewportParams) { const targetViewport = viewportParams.defaultViewport; const viewportConfig = viewportParams.viewports[targetViewport] || allViewports[targetViewport]; if (viewportConfig?.styles) { // 提取宽高数值,去掉px单位 const width = parseInt(viewportConfig.styles.width, 10); const height = parseInt(viewportConfig.styles.height, 10); // 修改jsdom视口 Object.defineProperty(window, 'innerWidth', { writable: true, configurable: true, value: width }); Object.defineProperty(window, 'innerHeight', { writable: true, configurable: true, value: height }); // 触发resize事件,保证监听视口变化的组件能正常更新 window.dispatchEvent(new Event('resize')); } } // 执行原有快照逻辑 const testFn = multiSnapshotWithOptions({ createNodeMock: (element) => element, }); return testFn({ story, context }); }; initStoryshots({ test: customSnapshotTest, stories2snapsConverter: new Stories2SnapsConverter({ snapshotsDirName: './__snapshots__', }), });
额外注意事项
- 如果你的组件使用
window.matchMedia做响应式判断,还需要额外模拟matchMedia的返回结果,和视口尺寸保持一致 - 若快照中还是读取不到正确的组件宽度,可以调整
createNodeMock逻辑,给DOM节点模拟正确的clientWidth/offsetWidth属性
内容的提问来源于stack exchange,提问作者GaelF
相关产品推荐
相关产品推荐

