首页
/ Storybook `swc` 主配置完整指南:在 `main.js|ts` 中深度定制 SWC 编译

Storybook `swc` 主配置完整指南:在 `main.js|ts` 中深度定制 SWC 编译

2026-09-07 21:05:55作者:邓越浪Henry

Storybook 的 main.js|ts 主配置文件中包含一个名为 swc 的顶层属性,用于定制基于 Webpack 的项目在启用编译器插件 @storybook/addon-webpack5-compiler-swc 后的 SWC 转译行为。本指南以 Storybook 官方 API 文档 及其配套代码片段 main-config-swc.md 为主体,结合本仓库源码中的默认预设实现,系统讲解该配置项的函数签名、适用前提、TypeScript 类型写法,以及从"切换 JSX 运行时"到"微调编译目标"的真实定制手段。读完你可以在自己的 Storybook 项目中安全地覆写 SWC 选项,并理解这些改动在编译链路中的实际作用位置。

适用范围与适用前提:什么情况下 swc 才会生效

swc 顶层配置并不是一个对所有 Storybook 项目都起作用的通用开关,它有明确的启用条件。根据 main-config-swc.mdx 的说明,该属性定制的是 Storybook 面向 Webpack 系项目的 SWC 转译设置,前提是项目已经通过 @storybook/addon-webpack5-compiler-swc 插件启用了 SWC 作为编译器。该插件覆盖绝大多数受支持的 Webpack 框架,但明确排除以下四类:

  • Angular(自带编译器体系)
  • Create React App(CRA)
  • Ember.js
  • Next.js

从仓库源码也能印证这一"卫星插件"定位:@storybook/addon-webpack5-compiler-swc@storybook/addon-webpack5-compiler-babel 一起被记录在 satellite-addons.ts 中,注释表明它们是"Storybook 维护、但不在本 monorepo 内的包"。换句话说,你可以通过 npm 正常安装它,但它不会出现在本仓库的 code/addons 目录中。另从文件结构看,Next.js 框架自带独立的 SWC loader 适配(例如 next-swc-loader-patch.ts),因此也被排除在上述插件的作用范围之外。

如果你的项目走的是 Babel 编译路线(即安装了 @storybook/addon-webpack5-compiler-babel),则不应使用 swc 属性,而应使用同级的 babel 主配置。两者的适用关系都可以在 主配置总览编译器相关文档 中进一步查阅。

配置签名:函数式覆写,支持同步与异步

swcStorybookConfigRaw 主配置类型 中被定义为"修改或返回 swc 配置"的入口。按官方文档,其完整类型签名为:

(config: swc.Options, options: Options) => swc.Options | Promise<swc.Options>
  • 第一个参数 config 是当前生效的 SWC 配置(类型来自 @swc/coreOptions),Storybook 与编译器插件会先为你组装出一份基线配置,再传入你的函数。
  • 返回值将被作为新的最终配置使用,因此你必须显式 return,并且通常通过 { ...config, ...你的改动 } 展开合并,避免丢失原有配置。
  • 返回类型允许是 Promise<swc.Options>,这意味着你可以在回调里执行异步逻辑(例如按需读取外部文件、判断构建模式后再决定编译参数),再返回处理后的配置。
  • 第二个参数 options 的类型为 { configType?: 'DEVELOPMENT' | 'PRODUCTION' },用于区分当前是 storybook dev 开发态还是 storybook build 生产构建,方便你对两种模式差异化处理。文档同时注明该对象还有其他难以在此一一列出的字段,需要以实际的类型定义为准进行自省(例如通过 IDE 跳转到 Options 类型查看)。

在 Storybook 内部,swc 属于预设(preset)扩展体系的一员:Presets.apply() 提供了专门的 apply(extension: 'swc', ...) 重载,见 core-common.ts 的 Presets 接口。也就是说,你在 main.js|ts 里写的 swc 函数本质上是被当作一个预设值注入编译链路的。

基线默认值:Webpack5 构建器预设了什么

要理解你覆写的对象从何而来,可以看本仓库中 Webpack5 构建器的默认 swc 预设实现 custom-webpack-preset.ts。它展示了 Storybook 在传给用户回调之前会准备的默认环境目标:

const newConfig = {
  ...config,
  env: {
    ...(config?.env ?? {}),
    targets: config?.env?.targets ?? {
      chrome: 100,
      safari: 15,
      firefox: 91,
    },
  },
};

// 将破碎语法转译为最接近的非破碎现代语法。
// 例如:不会转译 Safari 中的参数解构——那会破坏
// play 函数中 mount 上下文属性是否被使用的检测逻辑。
if (!shouldRemoveBugfixes) {
  newConfig.env.bugfixes = config?.env?.bugfixes ?? true;
}

这段源码揭示了两条重要事实:

  1. 默认编译目标:当你在 swc 回调中不做任何设置时,基线配置会面向 chrome 100 / safari 15 / firefox 91 等现代浏览器做转译,并且只在 env.targets 未被自定义时填充默认值。
  2. 默认开启 bugfixes:只要 main.js 中没有开启 features.babelRemoveBugfixes 特性(源码中通过 options.features.babelRemoveBugfixes 判断),就会默认启用 SWC 的 bugfixes。注释中解释了原因——它只做"最小的必要语法修复",例如对 Safari 中的参数解构做多余转译,从而保证 Storybook 检测 play 函数中 mount 上下文使用情况的代码逻辑不被破坏。这是一个在覆写 swc 时需要刻意保留的默认行为。

所以你的 swc 回调中 config 的第一行展开结果,通常就是带有上述 env 目标的基线配置。

完整配置模板:JS 与 TS、CSF3 与 CSF Next 四种写法

swc 属性需要书写在项目根目录下的 .storybook/main.js.storybook/main.ts 中。这里完整给出官方代码片段 main-config-swc.md 的全部写法,覆盖 JavaScript/TypeScript 与 CSF3/CSF Next 两代配置 API:

1. JavaScript + CSF3

export default {
  framework: {
    name: '@storybook/your-framework',
    options: {},
  },
  swc: (config, options) => {
    return {
      ...config,
      // Apply your custom SWC configuration
    };
  },
};

2. TypeScript + CSF3

import type { Options } from '@swc/core';

// Replace your-framework with the webpack-based framework you are using (e.g., react-webpack5)
import type { StorybookConfig } from '@storybook/your-framework';

const config: StorybookConfig = {
  framework: {
    name: '@storybook/your-framework',
    options: {},
  },
  swc: (config: Options, options): Options => {
    return {
      ...config,
      // Apply your custom SWC configuration
    };
  },
};

export default config;

3. TypeScript + CSF Next(实验性)

import type { Options } from '@swc/core';

// 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: {
    name: '@storybook/your-framework',
    options: {},
  },
  swc: (config: Options, options): Options => {
    return {
      ...config,
      // Apply your custom SWC configuration
    };
  },
});

4. JavaScript + CSF Next(实验性)

// 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: {
    name: '@storybook/your-framework',
    options: {},
  },
  swc: (config, options) => {
    return {
      ...config,
      // Apply your custom SWC configuration
    };
  },
});

四种写法的差异要点:

  • framework.name 占位符:CSF3 的 TypeScript 示例中,注释明确提示应替换为你实际使用的基于 Webpack 的框架包(例如 @storybook/react-webpack5);CSF Next 的示例则提示可替换为 react-vitenextjsnextjs-vite 等框架。占位符一律形如 @storybook/your-framework,直接照抄会导致配置无法解析。
  • CSF Next 的 defineMain:这是新一代类型安全配置 API 的入口,从 @storybook/<framework>/node 子路径导入,取代手写 const config: StorybookConfig + export default config 的模式,代码片段中 defineMain 已用 🧪 标注为实验性能力。
  • TypeScript 版本的类型来源Options 类型从 @swc/core 导入,保证回调参数与 SWC 官方类型严格对齐。
  • 必须返回新对象:四个示例都强调"扩展后返回",即用 { ...config } 展开原配置再叠加自定义项,确保不破坏基线(包括上述默认编译目标与 bugfixes)。

实战示例:覆写 React JSX 转换配置

配置片段 main-config-swc-jsx-transform.md 给出了一个真实且简短的定制场景——控制 React JSX 的转换运行时。例如希望 Storybook 编译 React 时强制使用 automatic 运行时(不再需要显式 import React,而是让编译器自动注入 jsx 运行时导入):

export default {
  framework: {
    name: '@storybook/your-framework',
    options: {},
  },
  swc: (config, options) => ({
    jsc: {
      transform: {
        react: {
          runtime: 'automatic',
        },
      },
    },
  }),
};

注意这里刻意没有展开 ...config——示例本身展示的是"整份替换"的语义:swc 回调的返回值就是最终配置。对于只想微调一两个字段、保留基线 env 目标与 bugfixes 的场景,上一节中的展开合并写法才是推荐做法;而当你希望完全接管编译行为、自行声明全部 SWC 选项(例如完整指定 jscenvmodule 等)时,直接返回整份配置同样是合法的。两种用法 API 文档均未禁止,取舍取决于你是否信任并需要 Storybook 注入的默认环境目标。

jsc.transform.react.runtime 只是 swc.Options 庞大选项空间的一角。SWC 的 Options 通常围绕以下几个顶层字段组织,你在覆写时均可按需设置:

顶层字段 作用 本场景中的相关子项
jsc JavaScript 解析与转换的核心配置 jsc.transform.react.runtime(classic/automatic)、jsc.parser(syntax、tsx、decorators)、jsc.target
env 面向运行环境的转译目标 env.targets(浏览器列表)、env.bugfixesenv.mode
module 模块输出格式 module.type(如 es6/commonjs
minify 是否启用压缩 布尔值或压缩配置对象

由于相关选项数量庞大且随 @swc/core 版本演进,官方文档的建议是:以项目实际安装的 @swc/core 类型定义为最终权威,在编辑器中对 Options 类型做自省,即可获得当前版本支持的完整字段清单与注释。

使用要点与注意事项

综合官方 API 文档、代码片段与源码实现,以下几点是使用 swc 主配置时必须注意的:

  1. 必须先启用对应编译器插件@storybook/addon-webpack5-compiler-swcswc 属性产生实际效果的先决条件。若未安装该插件,swc 回调中的改动不会参与编译;若使用的是 Babel 编译器插件,则请转向 babel 主配置。
  2. 框架适用范围有边界:仅对 Webpack 系且受支持的框架生效,Angular、CRA、Ember.js、Next.js 四类项目不适用,详见前文与 main-config-swc.mdx
  3. .storybook/main.js|ts 必须为合法 ESM:这是 主配置总览 中强调的硬性要求——文件内只能使用 import 而不能使用 require,同时 __dirname__filename 均不可用。
  4. 默认环境目标会被继承:若你采用 { ...config, ... } 的合并写法,Webpack5 构建器预设的 chrome 100 / safari 15 / firefox 91bugfixes: true 基线会继续生效;若你整份替换,则这些默认值将由你的配置自行决定。
  5. 配置入口位于主配置对象顶层swcframeworkstoriesaddonsbabelwebpackFinal 等同级,是主配置对象(config)的属性之一,而非嵌套在 framework.optionsaddons 内部。
  6. 必要时可区分开发/生产:通过 options.configType'DEVELOPMENT' | 'PRODUCTION')可在同一回调内对 storybook devstorybook build 输出差异化的 SWC 配置。

参考资料

本文内容对应的仓库资料集中整理如下,便于深入研读:

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

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388