Svelte Webpack5 환경에 Storybook 통합하기 + Chromatic 배포

작성 : 2024-05-25수정 : 2024-05-25

목차 펼치기

 Svelte + Webpack 5 + Storybook

Svelte + Webpack 5 + Storybook

머리말

Storybook는 Svelte를 위한 공식 문서도 제공해주고 있습니다. 하지만 공식 문서만으로 Svelte 프로젝트에 Storybook을 설치하기에는 다소 부족했고, 관련해서 나오는 자료도 많지 않았기에 실제 설치를 진행한 과정을 기록해봅니다.


들어가기 전에

이 글은 Webpack 5를 사용하고 있는 Svelte 프로젝트에 Storybook을 설치하고, Chromatic을 통해 배포하는 방법에 대해 설명하고 있습니다.


단, 몇 가지 방법을 시도해보았으나 Svelte의 중심 개념 중

slot은 Storybook에서 사용할 수 없었습니다.

(참고:

Svelte Slots #22774

) decorators를 이용해서 Story 컴포넌트를 slot을 통해 렌더링 하는 예제(

composite-component

)는 제공하고 있으나, Story 컴포넌트가 내부적으로 slot을 통해 구현되고 있다면 이를 구현해 줄 방법이 없었습니다.


하지만 저는 Storybook으로 구현할 컴포넌트는 중첩 구조가 없는 원자 단위의 컴포넌트만 구현할 것이기에 큰 이슈라고 생각하지는 않았습니다. 혹시 방법을 알고 계시다면 댓글로 가르쳐주시기를 부탁드리며, 그렇지 않다면 컴포넌트를 구현할 때 slot을 사용하지 않은 방법을 검토해주세요.


Svelte 스타일로 Story를 생성할 수 있도록 지원해주는

addon-svelte-csf

는 사용하지 않았습니다. (참고:

Integrate Storybook in Svelte: Doing it the Svelte-way

)


편의를 위해 이후 Svelte는 스벨트로, Storybook은 스토리북으로, Webpack 5는 웹팩으로 명칭하겠습니다.


스벨트에 스토리북 설정하기

스토리북 설치

javascript
1npx sb init --type svelte
2
3...install...
4
5We were not able to detect the right builder for your project. Please select one:
6Vite
7> Webpack 5
8
9...install...

스토리북을 위해 필요한 라이브러리를 설치해주고, 기본적인 환경설정 파일을 생성합니다.


만약 설치 과정 중 권한 오류인

EACCES: permission denied

오류가 발생한다면, sudo로 실행하기 보다 현재 프로젝트의

node_moduels

경로 및 하위 경로에 대해 전체 권한을 부여한 후 설치 명령어를 실행하는 것이 좋습니다. sudo로 진행하게 되면 이후 스토리북 관련 생성된 파일들도 모두 권한을 요구하게 되어 더 번거롭습니다.


설치 과정 중 Vite와 웹팩 중 프로젝트에서 사용 중인 번들러를 선택하는 질문이 나올 수 있는데, 웹팩을 선택해서 설치를 계속 합니다.


이후 설치 과정에서 자동으로 생성된 파일을 토대로 추가 설정을 진행하게 됩니다.

  • .storybook

    폴더에 기본 설정 파일이 생성됩니다.

  • /stories

    폴더 내에 기본 예시 코드가 생성됩니다.

  • package.json

    파일 내에 스토리북 실행 및 빌드 관련 스크립트가 생성됩니다.

    • npm run storybook

      : 저는 이 스크립트를

      npm run sb

      로 실행되도록 별칭을 변경했습니다.

    • npm run build-storybook

      : 이 명령어는 추후 Chromatic으로 배포할 때, 내부적으로 사용되는 명령어기 때문에 별칭을 변경하지 않고 그대로 사용합니다.


스토리북 웹팩 설정

typescript
1import type { StorybookConfig } from '@storybook/svelte-webpack5';
2import path from 'path';
3import sveltePreprocess from 'svelte-preprocess';
4
5const config: StorybookConfig = {
6  stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx|svelte)'],
7  addons: [
8    '@storybook/addon-links',
9    '@storybook/addon-essentials',
10    '@chromatic-com/storybook',
11    '@storybook/addon-interactions',
12  ],
13  framework: {
14    name: '@storybook/svelte-webpack5',
15    options: {},
16  },
17  docs: {
18    autodocs: 'tag',
19  },
20  webpackFinal: async config => {
21    if (config.module?.rules) {
22      const svelteLoader: any = config.module.rules.find((r: any) => r?.loader && r.loader.includes('svelte-loader'));
23      if (svelteLoader) {
24        svelteLoader.options.preprocess = sveltePreprocess({ sourceMap: true, typescript: true });
25      }
26
27      config.module.rules.push({
28        test: /\.(ts|tsx)$/,
29        use: [
30          {
31            loader: 'ts-loader',
32            options: {
33              transpileOnly: true,
34            },
35          },
36        ],
37        exclude: /node_modules/,
38      });
39    }
40
41    if (config.resolve?.alias) {
42      config.resolve.alias = {
43        ...config.resolve.alias,
44        svelte: path.resolve(__dirname, '../node_modules/svelte'),
45        '@': path.resolve(__dirname, '../src'),
46      };
47    }
48
49    if (config.resolve?.extensions) {
50      config.resolve.extensions.push('.mjs', '.js', '.ts', '.svelte');
51    }
52
53    return config;
54  },
55  typescript: { // 빌드 시간 단축을 위해
56    check: false,
57    checkOptions: {},
58  },
59};
60export default config;
61
webpackFinal

속성을 통해 프로젝트에서 사용하고 있는 웹팩 설정을 동일하게 적용해줄 수 있습니다. 위 코드는 최종적으로 적용한 코드입니다.


(필수) svelte-lodaer 설정
bash
1Module build failed (from ./node_modules/svelte-loader/index.js):

svelte-loader에 대해 설정하지 않으면, 스토리북 실행 시 위의 오류가 발생할 수 있습니다. 스벨트 파일 내 구문을 해석하지 못해서 발생하는 오류로 스토리북 리포지터리에서 생성되었던

를 참고했습니다.

svelteLoader

타입에 대해서는 any로 처리해버렸습니다.


(필수) ts-loader 설정
bash
1Module parse failed: Unexpected token

ts-loader에 대해 설정하지 않으면, 스토리북 실행 시 위의 오류가 발생할 수 있습니다. 웹팩이 TypeScript를 파싱할 수 있도록 설정해줍니다.


(옵션) 프로젝트에서 사용 중인 웹팩 설정 추가

그 외 프로젝트에서 사용 중인 웹팩 설정을 추가할 수 있으며, 여기서는 Alias와 확장자 설정 내용을 동일하게 추가했습니다.


스토리북 로컬 실행


이제

yarn sb

명령어를 통해 스토리북을 로컬에서 실행하면, 프로젝트 내에

{name}.stories.ts

형식으로 생성된 컴포넌트들을 확인할 수 있습니다. 처음 생성된

./stories

폴더를 삭제하지 않았다면, 기본적으로 제공해주는 예시 컴포넌트를 확인할 수 있습니다.


개인적으로는 이후 스토리북 코드를 작성할 때 Cursor IDE가 큰 도움이 되었습니다. 기존 컴포넌트 코드 입력 후 스토리북 코드 만들어달라고 요청한 후 조금만 수정하면 되어서 공식 문서를 보지 않고도 어느 정도의 작업이 가능했습니다.


스토리북 css-reset 설정

typescript
1import type { Preview } from '@storybook/svelte';
2import '../public/global.css';
3
4const preview: Preview = {
5  parameters: {
6    controls: {
7      matchers: {
8        color: /(background|color)$/i,
9        date: /Date$/i,
10      },
11    },
12  },
13};
14
15export default preview;
16

.storybook/preview.ts

프로젝트에서 브라우저에서 기본적으로 제공해주는 css를 무효화하기 위해 css-reset 코드를 사용하고 있거나, 그 외에도 전역 스타일 코드를 사용하고 있다면 스토리북에도 따로 적용해주어야 합니다. 그렇지 않을 경우 스토리북에서 보이는 컴포넌트와 실제 웹 어플리케이션에서 보이는 컴포넌트의 스타일이 상이할 수 있습니다.

.storybook/preview.ts

파일 내에 글로벌 css 파일을 import 하는 것으로 적용할 수 있습니다.


스토리북 로컬 빌드

bash
1npm run build-storybook

스토리북을 빌드하고 생성된 결과를

./storybook-static

폴더에 저장합니다. 이 경로를

.gitignore

에 추가합니다.


Chromatic으로 스토리북 배포하기


참고

Chromatic 설치

bash
1yarn add -D chromatic

프로젝트의 개발 의존성으로 chromatic 패키지를 설치합니다.


Chromatic 회원가입

Chromatic 공식 사이트

로 이동해서 회원가입을 진행합니다. Github, Bitbucket, Gitlab 계정과 SSO 연동이 가능하며, 이메일로도 회원가입이 가능합니다. 여기서는 이메일로 회원가입을 진행했습니다.


여러 사용자와 협업할 경우 배포가 완료된 스토리북 프로젝트에서 Collaborators를 초대합니다.


Chromatic 프로젝트 생성


이메일로 가입한 계정이기 때문에 Create Project만 가능합니다. 만약 외부 저장소와 연동된 계정이라면, 해당 계정의 리포지터리를 선택해서 프로젝트를 생성할 수도 있습니다.



프로젝트의 종류로는 스토리북을 선택해서 진행합니다.



프로젝트가 생성되면, 스토리북 배포를 위한 스크립트를 확인할 수 있습니다. 이 배포 스크립트에서 내부적으로

npm run build-storybook

을 사용하고 있습니다.


Chromatic 배포


배포 스크립트를 실행해서 성공하면 스토리북이 호스팅 된 URL과 해당 프로젝트를 관리할 수 있는 URL을 확인할 수 있습니다.

이후 Chromatic 배포 스크립트를

package.json

파일에 추가할 지 물어보는데,

y

를 눌러 추가해두면 편합니다.


여기까지 진행할 경우, 작업자의 계정으로는 배포된 스토리북에 접근할 수 있으나 다른 사용자들은 접근할 수 없습니다. 스토리북 프로젝트에 외부 협력자를 초대하는 것으로 해결할 수 있습니다. 문서의 다음 장을 확인해주세요.


Free Plan의 사용량


Chromatic에서 스토리북 배포 서비스의 요금 체계는 위와 같습니다. Free Plan은 월마다 5,000개의

Snapshot

을 사용할 수 있네요.


스토리북 외부 협력자 추가

Chromatic으로 배포된 스토리북은 보안 CDN에 배포되어 권한이 있는 계정이 아닐 경우 접근할 수 없습니다. 그렇기 때문에 여러 계정이 사용할 경우 프로젝트에 접근을 허용할 계정을 별도로 추가해주어야 합니다.


배포된 스토리북 URL로 접근한 뒤 좌측 하단에 조그맣게 있는 “

Back to Chromatic

”이라는 버튼을 클릭해서 프로젝트 관리 화면으로 이동합니다.



[Manage] - [Collaborate] - [Collaborators] - [Invite via email]을 클릭해서 이메일로 초청장을 보낼 수 있습니다.


이 때 권한은 Owner, Developer, Reviewer, Viewer로 구분됩니다.

Wanna get in touch?

All Icons byiconiFy