개발환경

Storybook 실행 오류 해결: Vite builder에서 Failed to fetch dynamically imported module이 날 때

2026.05.11·수정 2026.05.12·약 8분

이 글에서 정리하는 내용

Storybook에서 Failed to fetch dynamically imported module이 뜨면 컴포넌트 코드만 볼 문제가 아닙니다. Vite builder 캐시, alias, public 경로, addon 버전, 개발 서버의 모듈 URL이 서로 어긋난 상황을 순서대로 확인해야 합니다.

내 증상이 이거면 여기부터 보세요

Storybook 실행 오류 해결 원인 진단 흐름

Storybook은 앱 개발 서버와 비슷해 보이지만 별도의 Vite 환경에서 실행됩니다. 그래서 앱에서는 잘 열리는 컴포넌트도 Storybook 안에서는 alias, 정적 파일, 캐시, addon 버전 때문에 동적 import가 실패할 수 있습니다.

증상실제 에러 메시지먼저 볼 위치바로 해볼 조치이동할 섹션
브라우저 콘솔에 동적 import 실패Failed to fetch dynamically imported moduleStorybook 캐시/모듈 URL캐시 삭제 후 재실행핵심 수정 코드
앱은 되는데 Storybook만 alias 실패Cannot resolve alias @/componentsviteFinal alias앱 Vite alias와 동일하게 설정핵심 수정 코드
특정 story 파일만 실패Failed to load urlstory import 경로대소문자와 named export 확인예외 케이스
업데이트 후 갑자기 실패requested module does not provide exportaddon/framework 버전storybook 패키지 버전 정렬왜 생기는가

오류 해결 글에서는 실제 에러 문구가 본문에 있어야 검색해서 다시 찾기 쉽습니다. 프로젝트명, 사용자명, 토큰, 절대 경로처럼 민감하거나 불필요한 값은 빼고 대표 문구만 남깁니다.

TypeError: Failed to fetch dynamically imported module
Failed to load url /src/components/Button.stories.tsx
The requested module does not provide an export named
Cannot resolve alias @/components

먼저 적용할 핵심 수정 코드

원인 설명을 오래 읽기 전에 아래 설정부터 현재 코드와 대조해보세요. 먼저 Storybook 캐시를 비우고, main 설정의 framework/builder와 viteFinal alias를 실제 앱 설정과 맞춥니다. 중요한 것은 오류를 덮는 옵션을 추가하는 것이 아니라, 실행 환경과 설정 파일이 같은 기준으로 동작하게 만드는 것입니다.

Storybook Vite 설정 예시

import type { StorybookConfig } from "@storybook/react-vite"
import { fileURLToPath } from "node:url"

const config: StorybookConfig = {
  framework: "@storybook/react-vite",
  stories: ["../src/**/*.stories.@(ts|tsx)"],
  viteFinal: async (config) => {
    config.resolve = {
      ...config.resolve,
      alias: {
        ...config.resolve?.alias,
        "@": fileURLToPath(new URL("../src", import.meta.url)),
      },
    }
    return config
  },
}

export default config

앱에서 쓰는 alias를 Storybook Vite 환경에도 알려줘야 story import가 같은 기준으로 해석됩니다.

캐시 제거 후 재실행

rm -rf node_modules/.cache/storybook
rm -rf node_modules/.vite-storybook
npm run storybook

캐시 문제는 설정을 바꿔도 이전 모듈 URL이 남아 같은 오류처럼 보일 수 있습니다.

왜 이런 오류가 생기는가

Vite builder는 story 파일을 브라우저가 동적으로 불러오게 만듭니다. 이때 생성된 모듈 URL이 캐시에 남아 있거나 실제 파일 경로와 어긋나면 브라우저는 모듈을 가져오지 못합니다.

앱의 Vite 설정과 Storybook의 Vite 설정은 자동으로 완전히 같아지지 않습니다. alias, plugin, define 값이 앱에서는 있는데 Storybook에는 없으면 앱 전용 import가 story 안에서 깨집니다.

Storybook 패키지를 일부만 업데이트하면 framework, addon, builder 버전이 엇갈릴 수 있습니다. 이 경우 코드가 아니라 패키지 조합 때문에 모듈 export 오류가 보입니다.

실제 작업에서 점검하는 순서

첫 번째로 오류가 나온 단계를 나눕니다. 개발 서버에서만 보이는지, 빌드에서 실패하는지, 배포나 CI에서만 실패하는지에 따라 봐야 할 파일이 달라집니다. 같은 메시지라도 실행 위치가 다르면 원인도 다를 수 있습니다.

두 번째로 한 번에 여러 설정을 바꾸지 않습니다. Storybook Failed to fetch dynamically imported module를 해결하다 보면 관련 파일을 전부 고치고 싶어지지만, 그러면 어떤 변경이 실제 해결책이었는지 알기 어렵습니다. 핵심 설정 하나를 바꾸고 검증 명령을 실행한 뒤 다음 설정으로 넘어가야 합니다.

세 번째로 저장소에 남는 기준으로 정리합니다. 개인 PC에서만 통과하는 임시 조치가 아니라 설정 파일, 패키지 버전, 배포 설정처럼 팀원이 같은 기준으로 재현할 수 있는 형태가 되어야 합니다.

그래도 안 될 때 볼 예외 케이스

기본 수정 후에도 같은 메시지가 남는다면 캐시, 버전 차이, 경로 대소문자, 실행 위치를 같이 봐야 합니다. 오류 메시지는 하나처럼 보여도 실제로는 개발 서버, 타입 검사, 번들러, 배포 환경이 서로 다른 설정을 읽어서 생기는 경우가 많습니다.

  • 대소문자가 다른 import는 macOS에서 지나가도 Linux CI나 배포 환경에서 실패할 수 있습니다.
  • public 폴더 파일을 절대 경로로 참조한다면 Storybook staticDirs 설정을 확인합니다.
  • CSS 모듈이나 SVG loader를 앱에서만 설정했다면 Storybook viteFinal에도 같은 처리가 필요할 수 있습니다.

다음에 같은 문제를 줄이는 체크리스트

Storybook 실행 오류 해결 해결 단계 체크리스트

Storybook 오류는 컴포넌트 로직보다 실행 환경 차이에서 먼저 찾는 편이 빠릅니다. 앱 개발 서버와 Storybook 개발 서버가 같은 파일을 같은 방식으로 읽는지 확인하면 원인이 좁혀집니다.

  • Storybook 캐시를 비우고 재실행합니다.
  • framework가 @storybook/react-vite인지 확인합니다.
  • 앱 alias와 Storybook viteFinal alias를 맞춥니다.
  • addon과 storybook 패키지 버전을 함께 정렬합니다.

결국 Storybook Failed to fetch dynamically imported module는 한 줄짜리 우회 코드보다 확인 순서가 중요합니다. 에러 문구를 단계별로 나누고, 설정 파일과 실행 명령을 같은 기준으로 맞추면 같은 문제를 훨씬 짧게 끝낼 수 있습니다.

이 글이 마음에 드세요?

RSS 피드를 구독하세요!

댓글 남기기