스토리북을 Vue 단일 파일 구성 요소와 함께 사용

Storybook는 격리 설계, 작성, 테스트 구성 요소에 사용되는 우수한 도구이다.그것 때문에 우리는 진정한 응용 프로그램에서 그것들을 둘러싼 모든 코드와 업무 논리를 설정하지 않고 구성 요소를 만들고 테스트할 수 있다.한 번에 하나의 구성 요소를 개발하는 이야기책 작업 흐름도 봉인과 모듈화에 도움이 된다. 만약에 우리가 모든 구성 요소를 단독으로 개발한다면 응용 프로그램의 다른 부분과 결합된 구성 요소를 개발할 가능성이 적다.
Storybook은 처음에 React 구성 요소를 개발하는 도구였지만, 지금은 많은 다른 UI 프레임워크(Vue 포함)를 지원합니다.Vue를 사용하여 스토리북을 설정하는 것은 매우 쉽습니다. Vue의 단일 파일 구성 요소(SFC)를 통해 우리는 이야기를 작성하고 관련된 템플릿, 논리와 스타일을 같은 파일에 배치하며 스토리북 UI에서 원본 코드를 볼 수 있습니다.

Storybook을 사용하여 Vue CLI 항목 설정


Vue CLI를 사용하여 Storybook이 포함된 간단한 항목을 설정합니다.
  • 최신 버전의 Vue CLI 설치
  •   npm install -g @vue/cli
    
  • 기본 사전 설정을 사용하여 새 항목 만들기
  •   vue create vue-storybook-tutorial --default
    
  • 새로 만든 프로젝트 디렉터리로 전환하고 스토리북 설치
  •   cd vue-storybook-tutorial
      npx -p @storybook/cli sb init --type vue
    

    간단한 단추 구성 요소 만들기


    이제 간단한 단추 구성 요소를 만들어서 이야기를 작성합시다.이 구성 요소는 속성 color 을 가지고 있으며, 그 값은 (기본값) 또는 normal 입니다.
    <template>
        <button class="button" :class="`button-color--${color}`">
            <slot></slot>
        </button>
    </template>
    
    <script>
    export default {
        name: 'Button',
        props: {
            color: {
                type: String,
                default: 'normal', // 'normal' or 'primary'
            },
        },
    };
    </script>
    
    <style scoped>
    .button {
        appearance: none;
        border: none;
        font-family: sans-serif;
        padding: 8px 16px;
        border-radius: 2px;
    }
    
    .button-color--normal {
        background-color: #eee;
        color: #222;
    }
    
    .button-color--normal:hover,
    .button-color--normal:focus {
        background-color: #e0e0e0;
    }
    
    .button-color--normal:active {
        background-color: #bdbdbd;
    }
    
    .button-color--primary {
        background-color: #2196f3;
        color: #fff;
    }
    
    .button-color--primary:hover,
    .button-color--primary:focus {
        background-color: #1e88e5;
    }
    
    .button-color--primary:active {
        background-color: #1976D2;
    }
    </style>
    

    이야기를 쓰다


    설치 후 Storybook은 예제 스토리를 포함하는 디렉터리primary를 만듭니다.이 예시를 삭제하고 stories/ 단추 구성 요소에 자신의 이야기를 추가합니다.
    import Button from '../src/components/Button';
    
    export default {
        title: 'Button',
    };
    
    export const normalButton = () => ({
        components: { Button },
        template: '<Button>Normal Button</Button>',
    });
    
    export const primaryButton = () => ({
        components: { Button },
        template: '<Button color="primary">Normal Button</Button>',
    });
    
    위의 코드는 새로운 Component Story Format을 사용했는데, 이야기책 이외에 우리의 이야기를 사용할 수 있다는 좋은 장점이 있다. 예를 들어 우리의 자동 테스트에서.
    이제 스토리북을 실행하고 제공된 URL에 액세스하여 스토리를 볼 수 있습니다.
    yarn storybook
    

    이야기책 속 단추 구성 요소의 두 가지 이야기
    이렇게 해서 우리는 효과적인 이야기책 설정, 즉 suggested in the Storybook docs을 가지게 되었다.그러나 나는 문법이 밝고 다른 유용한 편집 컨트롤이 없기 때문에 문자열 템플릿에서 이야기를 작성하는 것을 좋아하지 않는다.또 다른 선택은 JSX를 작성하는 것입니다. 그러나 이 경우 JavaScript의 모든 기능이 필요하지 않다고 생각합니다.
    만약 우리가 Vue의 single file components stories/Button.stories.js 파일을 사용하여 이야기를 쓸 수 있다면?사실은 우리가 할 수 있다는 것을 증명한다!

    단일 파일 구성 요소에서 이야기 작성


    우리는 모든 이야기를 자신의 문서로 옮길 것이다.파일 이름의 .vue 접두사는 필요하지 않지만, 구성 요소로 이야기의 빠른 지시자일 수 있습니다..story :
    <template>
        <Button>Normal Button</Button>
    </template>
    
    <script>
    import Button from '../src/components/Button.vue';
    
    export default {
        name: 'ButtonNormal',
        components: { Button },
    };
    </script>
    
    stories/ButtonNormal.story.vue :
    <template>
        <Button color="primary">Primary Button</Button>
    </template>
    
    <script>
    import Button from '../src/components/Button.vue';
    
    export default {
        name: 'ButtonPrimary',
        components: { Button },
    };
    </script>
    
    새 구성 요소를 사용하기 위해 stories/ButtonPrimary.story.vue 업데이트:
    import ButtonNormal from './ButtonNormal.story.vue';
    import ButtonPrimary from './ButtonPrimary.story.vue';
    
    export default {
        title: 'Button',
    };
    
    export const normalButton = () => ButtonNormal;
    
    export const primaryButton = () => ButtonPrimary;
    
    현재 실행 stories/Button.stories.js 은 이전과 같은 이야기가 생길 수 있지만, 이번에는 단일 파일 구성 요소에서 작성되었습니다.

    우리는 무엇을 얻었습니까?


    보통 같은 일을 할 수 있는 방법이 다를 때, 모든 방법은 하나의 균형이 있다.이런 상황에서 이런 방법의 주요 단점은 현재 모든 이야기에 별도의 파일과 SFC 형식의 관련 샘플이 필요하다는 것이다.
    그러나 나는 우리가 얻은 것이 가치가 있다고 생각한다.
  • 구문 강조 표시 및 전체 편집기가 지원하는 관용 Vue 템플릿
  • 필요한 경우 이야기의 범위 CSS 스타일
  • 더 큰 이야기 조직 코드를 위한 더 깔끔한 방식
  • 우리는 여기까지 할 수 있지만, 이야기책 UI에 이야기의 출처를 보는 기능을 추가하는 중요한 개선을 할 수 있다.

    이야기책 속의 이야기 출처를 보다


    정부Storysource addon는 이야기책 속 이야기의 출처를 확인하는 지원을 늘렸다.불행하게도, 우리는 그것을 사용할 수 없다. 왜냐하면 이것은 이곳의 설정에서 작용하지 않기 때문이다. 그것은 우리가 이미 우리의 이야기를 내연적으로 썼다고 가정하지만, 우리는 그것을 사용하지 않는다. - 그것들은 단독 파일에서 가져온 것이다.
    우리의 이야기의 출처를 보기 위해서, 우리는 우리의 원본 패널로 이야기책 사용자 인터페이스를 확장해야 한다. 이 패널은 이 설정에 사용될 것이다.이를 위해 다음을 수행합니다.
  • yarn storybookcustom block을 저희 이야기 구성 요소 파일에 추가하고 사용자 정의 웹 마운트 프로그램을 작성하여 이야기 원본을 마운트합니다
  • Storybook UI에 소스 코드를 표시하는 플러그인 작성
  • <include source> SFC 블록 사용자 정의


    첫 번째 단계는 이야기 원본을 읽고 구축할 때 이야기 대상에 추가해서 실행할 때 UI에 표시할 수 있도록 하는 것이다.그러기 위해서는 두 가지 일이 필요하다.
  • 파일의 경로 <include-source> 를 가리키므로 읽을 수 있습니다
  • 원본 코드를 읽고 구성 요소에 추가하는 데 사용되는 패키지 캐리어
  • 불행하게도, 패키지 캐리어는 처리 중인 현재 코드 세그먼트 (또는 패키지 용어의'항목') 의 파일 경로에 직접 접근할 수 없습니다.그러나 그들이 확실히 얻을 수 있는 것은 상술한 항목의 출처이다.그래서 우리는 항목에 파일의 경로를 삽입해서 사용할 수 있다.
    Vue Loader의 사용자 정의 블록 기능을 사용하면 기본 .story.vue, <template>, <script> 블록 옆에 블록을 정의할 수 있습니다.Vue 로더는 분석 블록을 사용자 정의 패키지 로더에 전달하고, 이 로더는 분석을 받은 구성 요소에 대한 설명을 전달합니다.

    사용자 정의 블록 추가


    <include-source> 파일의 끝에 파일 경로가 있는 .story.vue 블록을 추가합니다.<include-source> :
    + <include-source>stories/ButtonNormal.story.vue</include-source>
    
    stories/ButtonNormal.story.vue :
    + <include-source>stories/ButtonPrimary.story.vue</include-source>
    
    이제 이야기책 패키지 설정을 확장하고 사용자 정의 블록을 처리하는 로드 프로그램을 추가합니다.stories/ButtonPrimary.story.vue에서 다음 내용을 포함하는 파일을 만듭니다.
    const path = require('path');
    
    module.exports = ({ config }) => {
        // Add a custom loader to load and attach the source of the file
        // specified in a <include-source> custom block of a Vue file
        config.module.rules.push({
            // The block type: <include-source>
            resourceQuery: /blockType=include-source/,
            // The custom loader: source-loader.js file in the current directory
            loader: path.resolve(__dirname, 'source-loader.js'),
            // Pass the repo's root path in the loader options to resolve the
            // relative source file paths
            options: {
                rootPath: path.resolve(__dirname, '..'),
            },
        });
    
        return config;
    };
    
    그리고 사용자 정의 로더를 사용하여 .storybook/webpack.config.js 에서 파일을 만듭니다.
    const fs = require('fs');
    const path = require('path');
    
    module.exports = function(source, sourceMap) {
        // `source` (the string in the custom <include-source> block) contains the file path
        const filePath = path.join(this.query.rootPath, source.trim());
    
        // Read the referenced file and remove the <include-source> block, so it doesn't
        // show up in the source code that will be shown in the UI
        const fileContent = fs
            .readFileSync(filePath, 'utf8')
            .replace(/<include-source>.*<\/include-source>\n/, '');
    
        // Generate a function that'll receive the Vue component and attach the source
        this.callback(
            null,
            `export default function (Component) {
                Component.options.__source = ${JSON.stringify(fileContent)};
            }`,
            sourceMap
        );
    };
    

    스토리북에 원본 패널 추가


    구축 기간에 모든 이야기의 원본을 상응하는 구성 요소에 추가하면 이야기책 플러그인을 작성하고 원본 코드를 표시하는 새 패널을 추가할 수 있습니다..storybook/source-loader.js에서 다음 내용을 포함하는 파일을 만듭니다.
    import React from 'react';
    import { addons, types } from '@storybook/addons';
    import { useParameter } from '@storybook/api';
    import { AddonPanel } from '@storybook/components';
    import { SyntaxHighlighter } from '@storybook/components';
    
    const ADDON_ID = 'vueStorySource';
    const PARAM_KEY = 'source';
    const PANEL_ID = `${ADDON_ID}/panel`;
    
    // The SourcePanel component (React)
    const SourcePanel = ({ active }) => {
        const source = useParameter(PARAM_KEY, null);
        return active && source
            ? React.createElement(
                    SyntaxHighlighter,
                    {
                        language: 'html',
                        showLineNumbers: false,
                        copyable: true,
                        padded: true,
                        format: false,
                    },
                    source
                )
            : null;
    };
    
    // Register the addon
    addons.register(ADDON_ID, () => {
        const render = ({ active, key }) =>
            React.createElement(
                AddonPanel,
                { active, key },
                React.createElement(SourcePanel, { active })
            );
    
        addons.add(PANEL_ID, {
            type: types.PANEL,
            title: 'Source',
            render,
            paramKey: PARAM_KEY,
        });
    });
    
    위의 코드는 .storybook/source-addon.js React 구성 요소를 정의합니다. 이 구성 요소는 SourcePanel Storybook 갈고리를 사용하여 이야기의 원본 코드를 가져오고 Storybook에 첨부된 useParameter 구성 요소를 사용하여 렌더링합니다.SyntaxHighlighter 매개 변수는 이야기의 source 대상에서 읽을 것입니다. 설정은 다음과 같습니다.

    매개 변수 보조 함수

    story() 파라미터를 추가하려면 source 구성 요소의 원본을 가져와 정의할 때 이야기 대상에 추가해야 합니다.우리는 모든 이야기에 대해 이렇게 할 것이기 때문에, 이 논리를 봉인하기 위해 .story.vue 보조 함수를 작성합시다.story에서 다음 내용을 포함하는 새 파일을 만듭니다.
    export function story(StoryComponent, options = {}) {
        // Get the `withSource` option, default to true. Making this an option
        // allows us to opt-out of displaying the source of a story.
        const { withSource } = Object.assign({ withSource: true }, options);
    
        // The story export that Storybook will use
        const storyExport = () => StoryComponent;
    
        // Attach the source as a story paramter
        if (withSource) {
            storyExport.story = {
                parameters: {
                    // `.__source` is from our custom <include-source> SFC block
                    // and webpack loader
                    source: StoryComponent.__source,
                },
            };
        }
    
        return storyExport;
    }
    
    현재, 우리는 stories/story.js의 모든 이야기의 정의를 업데이트하여, 이 조수를 사용하고, 이 조수는 추가 원본을 이야기 매개 변수로 삼는다.
    import { story } from './story';
    import ButtonNormal from './ButtonNormal.story.vue';
    import ButtonPrimary from './ButtonPrimary.story.vue';
    
    export default {
        title: 'Button',
    };
    
    export const normalButton = story(ButtonNormal);
    
    export const primaryButton = story(ButtonPrimary);
    
    만약 우리가 어떤 이야기에서 원본 코드를 사용하고 싶지 않다면, stories/Button.stories.js 함수에 두 번째 매개 변수로 { withSource: false } 원본 코드 첨부를 비활성화할 수 있습니다.
    export const storyWithDisabledSource = story(MyStory, { withSource: false });
    

    Storybook에 소스 플러그인 등록


    이야기책에서 우리의 새 판넬을 보려면 마지막 일은 플러그인을 등록하는 것이다.새 플러그인을 가져오고 등록하려면 업데이트story():
    import '@storybook/addon-actions/register';
    import '@storybook/addon-links/register';
    
    import './source-addon';
    
    현재 실행 중인 .storybook/addons.js 은 선택한 이야기의 원본을 표시할 새 패널 원본을 추가해야 합니다.

    단추 구성 요소의 두 가지 이야기와 이야기책의 출처

    결론


    이 글에서 나는 단일 파일 구성 요소에서 이야기를 작성하는 좋은 설정을 보여 주어 이야기책 속의 이야기의 출처를 볼 수 있다.나는 아래의 평론에서 이 방면에 관한 문제에 대답해서 매우 기쁘다.
    이 글의 전체 소스 코드는 GitHub에서 참조할 수 있습니다 https://github.com/JosephusPaye/vue-storybook-tutorial.
    이 글은 경량급 재료의 계발을 받은 Vue UI 구성 요소 라이브러리입니다.사용 중인 이 설정의 실제 예제를 보려면 Keen UI 을 보십시오.

    이야기책 보충하다


    이 글은 나의 일부분이다. 나는 2020년에 매주 공개적으로 새로운 것을 창조하려고 한다.

    좋은 웹페이지 즐겨찾기