首页
/ Storybook logLevel 配置详解:用 main.js 控制浏览器端日志级别,快速定位问题

Storybook logLevel 配置详解:用 main.js 控制浏览器端日志级别,快速定位问题

2026-09-07 10:41:48作者:蔡怀权

导读:本文基于 Storybook 官方 API 文档 main-config-log-level.mdx 与其配套代码片段 main-config-log-level.md,系统讲解如何在 .storybook/main.js(或 .storybook/main.ts)中通过 logLevel 字段配置 Storybook 运行在浏览器终端里的日志输出级别。读完本文,你将掌握 debug / error / info / trace / warn 五个级别的取舍、三种主流配置写法(CSF 3 与实验性的 CSF Next / defineMain 形式),并能依据仓库源码理解该配置从 main.ts 一路传递到浏览器端日志基础设施的完整链路,从而在排查构建与运行时问题时快速切换日志详略度。

logLevel 是 Storybook main.js|ts 配置 家族的成员之一。官方文档对其用途的概括非常精炼——配置 Storybook 在浏览器终端(browser terminal)中的日志,主要用于调试场景。当某个 addon、preview 逻辑或 Story 渲染在浏览器控制台中的行为异常、但默认日志信息不足时,把 logLevel 临时调到 debug 甚至 trace,是定位问题的最直接手段。

取值类型与默认值

在官方 API 参考中,logLevel 的属性定义如下:

  • 类型'debug' | 'error' | 'info' | 'trace' | 'warn'
  • 默认值'info'

也就是说,Storybook 默认只输出 info 及以上(按常规日志语义即信息、警告与错误)的日志;只有当你显式把它提高到 debugtrace 时,浏览器控制台才会出现更细粒度的调试与跟踪信息。反向地,如果你希望控制台尽量安静、只保留错误,可以把级别压到 error

这一默认值在仓库的 preset 实现中有直接佐证。在 common-preset.ts 中可以看到其核心逻辑:

export const logLevel = (previous: any, options: Options) => previous || options.loglevel || 'info';

从源码可以看出两点:

  1. 若没有任何配置,最终值回退为 'info',与官方文档默认值一致;
  2. 优先级顺序是 previous(已通过 preset 链注入/合并的前置值)> options.loglevel(命令行或工具链层面传入的日志级别选项)> 'info'。这也是为什么该字段允许在 main.ts 中被其他 preset 或上层工具覆盖。

在类型层面,Storybook 的 StorybookConfigRaw 与公开的 StorybookConfig 接口都声明了该字段,见 core-common.tscore-common.ts

// StorybookConfigRaw
logLevel?: string;

// StorybookConfig(公开给用户的 main.ts 类型)
logLevel?: PresetValue<StorybookConfigRaw['logLevel']>;

注意这里底层类型被声明为 string,而文档收窄到五个合法字符串字面量,因此实际使用时请以文档给出的五种取值为准;PresetValue<...> 的包装则意味着它既可写死为一个字符串,也可写成一个按环境返回字符串的取值函数。

如何在 main.js / main.ts 中配置

logLevelframeworkstories 等字段平级,直接放在导出的默认配置对象中即可。官方配套片段 main-config-log-level.md 展示了最常用的两种书写风格。

方式一:CSF 3 风格(export default 普通对象)

在不启用实验性 API 的情况下,.storybook/main.js 写法如下(替换 your-framework 为你实际使用的框架,例如 react-vitenextjsvue3-vite 等):

export default {
  // Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc.
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  logLevel: 'debug',
};

对应使用 TypeScript 编写配置时,.storybook/main.ts 写法如下,其中 StorybookConfig 类型同样按你所用的框架包导入:

// Replace your-framework with the framework you are using, e.g. react-vite, nextjs, vue3-vite, etc.
import type { StorybookConfig } from '@storybook/your-framework';

const config: StorybookConfig = {
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  logLevel: 'debug',
};

export default config;

方式二:CSF Next 风格(defineMain

在新一代配置 API(官方代码片段中以 CSF Next 🧪 标注,属于实验性特性)中,配置通过各框架包导出的 defineMain 包装。官方片段给出了一条通用规则:@storybook/<framework>/node 导入 defineMain,例如 React 相关渲染器用 @storybook/react-vite/node(或 nextjsnextjs-vite 等,以注释中的 your-framework 占位),而 Vue 3、Angular、Web Components 则分别使用各自的框架包路径:

// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, nextjs-vite)
import { defineMain } from '@storybook/your-framework/node';

export default defineMain({
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  logLevel: 'debug',
});

同样的 defineMain 写法也支持 JavaScript 文件(.storybook/main.js),且官方片段指出在当前阶段同时保留 JS 与 TS 变体是必要的:

// Replace your-framework with the framework you are using (e.g., react-vite, nextjs, nextjs-vite)
import { defineMain } from '@storybook/your-framework/node';

export default defineMain({
  framework: '@storybook/your-framework',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  logLevel: 'debug',
});

按渲染器拆分,CSF Next 变体针对不同框架的具体导入路径如下表所示(均可写成 .main.ts.main.js,配置体与上文一致):

渲染器 / 框架 defineMain 导入路径 framework 字段示例
React(含 Vite/Next 系) @storybook/react-vite/node 等框架包 @storybook/react-vite
Vue 3 @storybook/vue3-vite/node @storybook/vue3-vite
Angular @storybook/angular/node @storybook/angular
Web Components @storybook/web-components-vite/node @storybook/web-components-vite

以 Vue 3 与 Angular 为例,完整的 CSF Next 写法为:

import { defineMain } from '@storybook/vue3-vite/node';

export default defineMain({
  framework: '@storybook/vue3-vite',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  logLevel: 'debug',
});
import { defineMain } from '@storybook/angular/node';

export default defineMain({
  framework: '@storybook/angular',
  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
  logLevel: 'debug',
});

提示:storiesframework 字段并非 logLevel 主题的必需部分,仅为保证示例可独立运行而保留;你完全可以在既有配置对象上只追加 logLevel: 'debug' 一行。需要查看所有可同层配置的字段时,可回到 main-config.mdx 的索引继续查阅。

浏览器端日志:配置值如何被消费

理解 logLevel 的价值在于弄清楚它作用在哪一层。官方文档明确指出它面向的是 browser terminal(浏览器终端,即浏览器开发者工具的控制台),这区别于 Storybook Node 服务端/CLI 的终端日志(后者由 storybook/internal/node-logger 负责,例如 builder-manager/index.tslogger.step('Building manager..')logger.trace(...) 一类输出)。也就是说,调大 logLevel 后,你应当到 Storybook 页面所在的浏览器控制台 查看新增的调试信息,而不是看启动 Storybook 的终端窗口。

从源码结构看,logLevel 从配置到浏览器端的传递链路大致如下:

  1. Preset 解析:核心服务器通过 preset 机制取值。在 common-preset.ts 中导出的同名 preset 负责把用户配置(或 options.loglevel)规约为最终字符串并给出 'info' 兜底;
  2. Manager 构建数据准备:在 builder-manager/utils/data.ts 中,构建 manager 的数据准备阶段通过 options.presets.apply<string>('logLevel') 读取解析结果,并将其并入后续传给模板的数据对象(源码第 37 行的 logLevel 字段);
  3. 注入浏览器模板:在 builder-manager/utils/template.ts 中,logLevel 作为一个 Promise<string> 被消费,并以 LOGLEVEL: JSON.stringify(await logLevel, null, 2) 的形式注入生成的模板环境,最终随 manager 页面/资源进入浏览器端。

由此可以推断,浏览器端日志基础设施会在启动阶段读取注入的 LOGLEVEL,并据此决定哪些级别的日志应当输出到控制台——这就是“改一个 main.ts 字段即可全局切换浏览器端日志详略度”的实现基础。由于该值在构建阶段即被固化进模板,修改 logLevel 后需要让 Storybook(storybook dev 开发服务器或 storybook build 静态构建)重新加载/构建才能生效。

实战建议:什么时候选哪个级别

结合文档定义与源码中的日志调用点,可参考以下取舍策略:

  • info(默认):日常开发与 CI 构建使用。输出关键信息、警告与错误,控制台不会太嘈杂;这也是不配置该字段时的默认行为,与 common-preset.ts|| 'info' 兜底完全一致。
  • debug:排查 Storybook 行为异常时首选。官方文档明确描述 logLevel 字段"useful for debugging",把配置项的值改成 'debug' 即可获得比默认更丰富的浏览器端日志。
  • trace:需要最细粒度跟踪(例如观察 manager 构建产物、事件流等极细节输出)时使用。仓库中 builder-manager/index.ts 一类 logger.trace({ message: 'Manager built', ... }) 的调用即属此类,浏览器端同样存在对应的跟踪级日志点。
  • warn / error:希望控制台只保留警告或仅保留错误时使用,适合在演示或对日志输出敏感的自动化场景下收紧输出。

需要留意的是:logLevel 只影响浏览器端日志的门槛,不会隐藏已发生的问题本身。若你在浏览器控制台看不到期望的调试信息,请先确认取值字符串拼写正确(合法值仅为 debugerrorinfotracewarn),并确认 Storybook 已重新加载;若问题出在 Storybook 启动与构建阶段(Node 侧),则应转而检查 CLI/终端输出。

小结

logLevel 是 Storybook main.js|ts 配置中面向调试的轻量开关:一个字段、五种取值、默认 info。无论是手写 export default 的 CSF 3 风格,还是通过 defineMain 包裹的实验性 CSF Next 风格,只需把 logLevel: 'debug'(或更细的 'trace')加入配置对象,即可让 Storybook 在浏览器控制台输出更详细的运行日志;从 core-common.ts 的类型声明到 common-preset.ts 的默认值回退,再到 template.tsLOGLEVEL 注入,仓库源码完整印证了这条“配置 → preset 规约 → manager 模板注入 → 浏览器端生效”的实现链路。下次遇到 Storybook 界面行为诡异却无从下手时,不妨先把它调到 debug 看一次控制台。

登录后查看全文
热门项目推荐
相关项目推荐