From e9b641cfb73d23beb59753d5e4569512f11ec295 Mon Sep 17 00:00:00 2001 From: Jin Yi Date: Sun, 9 Nov 2025 02:40:33 +0900 Subject: [PATCH] [bugfix] Fix Storybook _sfc_main undefined error after v1.29.3 (#6635) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Fixes Storybook rendering issue where all components fail to load with `_sfc_main is not defined` error in **local development** since v1.29.3. ## Problem After upgrading to v1.29.3, all Storybook components fail to render **in local development** (`pnpm storybook`) with the following error: ``` ReferenceError: _sfc_main is not defined The component failed to render properly, likely due to a configuration issue in Storybook. ``` **Important**: This issue only affects **local development** environments. The deployed/built Storybook works correctly. This affects both: - Main Storybook (`pnpm storybook`) - Desktop-ui Storybook instances ## Root Cause In v1.29.3, commit `64430708e` ("perf: tree shaking and minify #6068") enabled build optimizations in `vite.config.mts`: ```typescript // Before (v1.29.2) rollupOptions: { treeshake: false } esbuild: { minifyIdentifiers: false } // After (v1.29.3) rollupOptions: { treeshake: true // ⚠️ Enabled } esbuild: { minifyIdentifiers: SHOULD_MINIFY // ⚠️ Conditionally enabled } ``` While these optimizations are beneficial for production builds, they cause issues in **Storybook's local dev server**: 1. **Tree-shaking in dev mode**: Rollup incorrectly identifies Vue SFC's `_sfc_main` exports as unused code during the dev server's module transformation 2. **Identifier minification**: esbuild minifies `_sfc_main` to shorter names in development, breaking Storybook's HMR (Hot Module Replacement) and dynamic module loading Since Storybook's `main.ts` inherits settings from `vite.config.mts` via `mergeConfig`, these optimizations were applied to Storybook's dev server configuration, causing Vue components to fail rendering in local development. **Why deployed Storybook works**: Production builds have different optimization pipelines that handle Vue SFCs correctly, but the dev server's real-time transformation breaks with these settings. ## Solution Added explicit build configuration overrides in both Storybook configurations to ensure the **dev server** doesn't inherit problematic optimizations: **Files changed:** - `.storybook/main.ts` - `apps/desktop-ui/.storybook/main.ts` **Changes:** ```typescript esbuild: { // Prevent minification of identifiers to preserve _sfc_main in dev mode minifyIdentifiers: false, keepNames: true }, build: { rollupOptions: { // Disable tree-shaking for Storybook dev server to prevent Vue SFC exports from being removed treeshake: false, // ... existing onwarn config } } ``` This ensures Storybook's **local development server** prioritizes stability and debuggability over bundle size optimization, while production builds continue to benefit from tree-shaking and minification. ## Testing 1. Cleared Storybook and Vite caches: `rm -rf .storybook/.cache node_modules/.vite` 2. Started local Storybook dev server with `pnpm storybook` 3. Verified all component stories render correctly without `_sfc_main` errors 4. Ran `pnpm typecheck` to ensure TypeScript compilation succeeds 5. Tested HMR (Hot Module Replacement) works correctly with component changes ## Context - This is a **local development-only** issue; deployed Storybook builds work fine - Storybook dev server requires special handling because it dynamically imports and hot-reloads all stories at runtime - Vue SFC compilation generates `_sfc_main` as an internal identifier that must be preserved during dev transformations - Development tools like Storybook benefit from unoptimized builds for better debugging, HMR, and stability - Production builds remain optimized with tree-shaking and minification enabled ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6635-bugfix-Fix-Storybook-_sfc_main-undefined-error-after-v1-29-3-2a56d73d36508194a25eef56789e5e2b) by [Unito](https://www.unito.io) --- .storybook/main.ts | 7 +++++++ apps/desktop-ui/.storybook/main.ts | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/.storybook/main.ts b/.storybook/main.ts index d61f72eae..4c03c3a51 100644 --- a/.storybook/main.ts +++ b/.storybook/main.ts @@ -74,8 +74,15 @@ const config: StorybookConfig = { '@': process.cwd() + '/src' } }, + esbuild: { + // Prevent minification of identifiers to preserve _sfc_main + minifyIdentifiers: false, + keepNames: true + }, build: { rollupOptions: { + // Disable tree-shaking for Storybook to prevent Vue SFC exports from being removed + treeshake: false, onwarn: (warning, warn) => { // Suppress specific warnings if ( diff --git a/apps/desktop-ui/.storybook/main.ts b/apps/desktop-ui/.storybook/main.ts index 91c29eb7a..d425d550b 100644 --- a/apps/desktop-ui/.storybook/main.ts +++ b/apps/desktop-ui/.storybook/main.ts @@ -75,8 +75,15 @@ const config: StorybookConfig = { '@frontend-locales': process.cwd() + '/../../src/locales' } }, + esbuild: { + // Prevent minification of identifiers to preserve _sfc_main + minifyIdentifiers: false, + keepNames: true + }, build: { rollupOptions: { + // Disable tree-shaking for Storybook to prevent Vue SFC exports from being removed + treeshake: false, onwarn: (warning, warn) => { // Suppress specific warnings if (