You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js项目中Storybook如何为每个Story单独Mock模块?

解决Next.js+Storybook中单个Story的模块Mock问题

方案1:手动修改require.cache实现模块Mock

不需要额外插件,直接在单个Story文件里修改Node.js的模块缓存,覆盖目标模块的导出,完全自定义Mock逻辑:

// 你的组件文件(比如ColorComponent.js)
import randomColor from "randomcolor";

export const ColorComponent = () => {
  const color = randomColor();
  return <div style={{ backgroundColor: color }}>Colored Box</div>;
};
// 对应的Story文件(ColorComponent.stories.js)
import { ColorComponent } from "./ColorComponent";

// 保存原始模块引用,避免影响其他Story
let originalRandomColor;

export default {
  title: "ColorComponent",
  component: ColorComponent,
};

// 单个Mock的Story
export const MockedFixedColor = () => {
  // 覆盖randomcolor模块的导出
  originalRandomColor = require.cache[require.resolve("randomcolor")];
  require.cache[require.resolve("randomcolor")] = {
    ...originalRandomColor,
    exports: {
      default: () => "#123456", // 自定义Mock返回值
    },
  };

  return <ColorComponent />;
};

// 组件卸载后恢复原始模块,防止污染其他Story
MockedFixedColor.parameters = {
  docs: {
    story: {
      afterRender: () => {
        if (originalRandomColor) {
          require.cache[require.resolve("randomcolor")] = originalRandomColor;
          originalRandomColor = null;
        }
      },
    },
  },
};

方案2:用mock-require库简化动态Mock

这个库封装了模块Mock的逻辑,操作更简洁,支持单个Story的独立Mock:

  1. 先安装依赖:
npm install mock-require --save-dev
  1. 在Story中使用:
import mockRequire from "mock-require";
import { ColorComponent } from "./ColorComponent";

export default {
  title: "ColorComponent",
  component: ColorComponent,
};

export const MockedWithLibrary = () => {
  // Mock randomcolor模块
  mockRequire("randomcolor", () => "#123456");
  // 重新加载组件,确保使用Mock后的模块
  const { ColorComponent: MockedComponent } = mockRequire.reRequire("./ColorComponent");

  return <MockedComponent />;
};

// 清理Mock,恢复原始模块
MockedWithLibrary.parameters = {
  docs: {
    story: {
      afterRender: () => {
        mockRequire.stop("randomcolor");
      },
    },
  },
};

方案3:针对React内置Hook的Mock(比如useMemo)

如果是MockReact内置Hook(如useMemo),可以用Storybook环境自带的jest.spyOn实现:

import React, { useMemo } from "react";
import { ComponentUsingUseMemo } from "./ComponentUsingUseMemo";

export default {
  title: "ComponentUsingUseMemo",
  component: ComponentUsingUseMemo,
};

export const MockedUseMemoBehavior = () => {
  // Spy并Mock useMemo,强制同步执行回调
  const originalUseMemo = useMemo;
  jest.spyOn(React, "useMemo").mockImplementation((fn) => fn());

  return <ComponentUsingUseMemo />;
};

// 恢复原始Hook,避免影响其他Story
MockedUseMemoBehavior.parameters = {
  docs: {
    story: {
      afterRender: () => {
        React.useMemo.mockRestore();
      },
    },
  },
};

关键注意事项

  • 所有Mock操作必须在Story结束后恢复原始模块/Hook,否则会污染全局运行环境,导致其他Story出现异常。
  • 针对Next.js的SSG/SSR相关模块,要确保Mock逻辑在组件渲染前执行,避免模块提前加载导致Mock失效。

内容的提问来源于stack exchange,提问作者Ahmed fouad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 15:02:57