본문 바로가기

Frontend Development/Vue.js

[Vue.js] Storybook custom webpack, preview 추가

Storybook을 현재 개발중인 프로젝트에 적용하기 위해서는 현재 Project 에 적용되고 있는 Webpack config나 특정 entry 함수가 필요할 경우가 많다 이럴 경우 아래 설정들을 추가해 두면 현재 프로젝트 설정도 하고 Storybook도 이용할 수 있다.

 

webpackFinal 함수 추가

 

아래와 같이 기본 실행되는 main.js파일에 webpackFinal 함수를 추가하고 webpack config를 확장한다.

 

.storybook/main.js

const path = require('path');
const resolve = (dir) => {return path.join(__dirname, '..', dir);};
const createCompiler = require('@storybook/addon-docs/mdx-compiler-plugin');

module.exports = {
  "stories": [
    "../src/**/*.stories.mdx",
    "../src/**/*.stories.@(js|jsx|ts|tsx)"
  ],
  "addons": [
    "@storybook/addon-links",
    "@storybook/addon-essentials"
  ],
  "framework": "@storybook/vue",
  webpackFinal: async (config, { configType }) => {
    // `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
    // You can change the configuration based on that.
    // 'PRODUCTION' is used when building the static version of storybook.

    config.resolve.extensions.push('.scss');
    config.resolve.alias = {...config.resolve.alias, ...{
        '@': resolve('src/main/vue'),
        '~': resolve('src/main/vue/lego'),
        '@pjt': resolve('src/main/vue/pjt'),
        '@image': resolve('src/main/vue/asset/img'),
        '@font': resolve('src/main/vue/asset/font'),
        '@style': resolve('src/main/vue/style'),
        '@const': resolve('src/main/vue/util/const.js')
    }};
	=> config의 resolve 항목이 필요하다면 여기서 추가할 수 있다.

    let isNotProduction = true;

    console.log(config);
    return { ...config, module: { rules: [{
          test: /\.vue$/, loader: 'vue-loader', options: {
            loaders: {
              scss: [
                'vue-style-loader',
                {loader: 'css-loader', options: {sourceMap: isNotProduction}},
                {loader: 'sass-loader', options: {data: `@import '@style/customConfig/customToken.scss';`, sourceMap: isNotProduction}}
              ]
            },
            transformAssetUrls: {
              img: 'src'
            }
          }
        },
          {
            test: /\.scss$/, loaders: [
              'style-loader',
              {loader: 'css-loader', options: {sourceMap: isNotProduction}},
              {loader: 'sass-loader', options: {data: `@import '@style/customConfig/customToken.scss';`, sourceMap: isNotProduction}},
            ]
          },
          {test: /\.css$/, loaders: ['vue-style-loader', 'css-loader']},
          {
            test: /\.js$/, loader: 'babel-loader',
            include: [
              resolve('src/main/vue'),
              resolve('/node_modules/vue2-dropzone'),
              resolve('node_modules/vue-echarts'),
              resolve('node_modules/resize-detector')
            ]
          },
          {
            test: /\.(png|jpg|jpeg|gif|svg|mp4)$/, loader: 'file-loader',
            options: {name: 'asset/media/[name].[ext]'}
          },
          {
            test: /\.(woff2?|eot|ttf|otf)?$/, loader: 'file-loader',
            options: {name: 'asset/fonts/[name].[ext]'}
          },
          {
            test: /\.(stories|story)\.mdx?$/,
            use: [
              {
                loader: 'babel-loader',
                options: {
                  plugins: ['@babel/plugin-transform-react-jsx'],
                },
              },
              {
                loader: '@mdx-js/loader',
                options: {
                  compilers: [createCompiler({})],
                },
              },
            ],
          }] => 현재 사용하는 프로젝트의 Loader들이 필요하다면 여기서 정의해서 추가한다.
    } };
  },
}

 

또한 webpack config 외에 프로젝트 설정을 위해 실행해야 하는 메소드가 있다면 storybook에서 제공하고 있는 preview.js 파일에 메소드를 정의 해 storybook실행 시에 실행 및 결과 확인을 할 수 있다.

 

.storybook/preview.js

import('./customEntry');

export const parameters = {
  actions: { argTypesRegex: "^on[A-Z].*" },
  controls: {
    matchers: {
      color: /(background|color)$/i,
      date: /Date$/,
    },
  },
}

=> preview.js 상단에 import로 처음에 실행하고자 하는 메소드를 import 해준다. 그러면 storybook 실행 시 초기에 불려서 프로젝트가 정상 동작하게 해준다.

 

 

.storybook/customEntry.js

import Lib from '@/util/global/lib';
import Loadd from '@/util/global/loader';
import Builder from '@/util/global/builder';

// don't use arrow function
// noinspection JSIgnoredPromiseFromCall
Load({

    data: {
        i18n : {},
        lego: {},
    },
    
    ...

=> 위와 같이 순수 Entry function안에 설정할 내용을 넣는다.

 

-- The end --