Nuxt.js + Storybook 통합하기
Storybook 공식홈페이지에는 Storybook에 Vue를 통합을 위한 가이드가 있습니다. 같은 Vue.js 기반의 Nuxt.js는 vue-cli 프로젝트와 다르게, 프로그램 시작점인 main.js를 사용자에게 제공하지 않기 때문에…

Storybook 공식홈페이지에는 Storybook에 Vue를 통합을 위한 가이드가 있습니다. 같은 Vue.js 기반의 Nuxt.js는 vue-cli 프로젝트와 다르게, 프로그램 시작점인 main.js를 사용자에게 제공하지 않기 때문에 Storybook을 설정하기가 쉽지 않습니다.
위 이유 때문에 다른 CSS프레임워크를 사용하고 있는 경우 .storybook
의 config.js
파일을 Vue 프로젝트의 main.js
라고 간주하여 설정을 하여야 합니다.
이번 글에서는 Tailwindcss를 사용하는 Nuxt.js 프로젝트에 Storybook을 추가하는 방법을 안내합니다.
Tailwindcss는 PostCSS를 이용하는 라이브러리입니다. Nuxt.js는 webpack을 번들러로 사용하므로 postcss-loader를 이용해 tailwindcss를 번들링합니다.
npx create-nuxt-app my-app
터미널에서 위 명령어를 이용해 Nuxt.js 앱을 만듭니다. CSS 프레임워크 / 라이브러리를 고를 때 꼭 Tailwindcss를 선택해주세요
npm install --save-dev @storybook/vue babel-core
위 명령어를 입력하면 Vue를 위한 Storybook을 프로젝트 의존성 목록에 추가합니다. 다음 명령어로 Storybook에 필요한 파일들을 만듭니다.
mkdir .storybook
touch config.js
touch webpack.config.js
cp postcss.config.js ./.storybook
첫번째로 config.js 폴더에서 프로젝트를 구성합니다.
// config.js
import { configure } from '@storybook/vue';
import 'tailwindcss/dist/tailwind.min.css'
import '../assets/css/tailwind.css'
import Vue from 'vue';
// import Vuex from 'vuex'; // Vue plugins
const req = require.context('../components', true, /\.story\.js$/)
function loadStories() {
req.keys().forEach((filename) => req(filename))
}
configure(loadStories, module);
앞서 말한 것 처럼 Vue.js 프로젝트의 main.js 파일로 간주하여 유사하게 프로젝트를 셋팅하면됩니다.
// postcss.config.js
const join = require('path').join
const tailwindJS = join(__dirname, '..', 'tailwind.js')
console.log('tailwindJS => ', tailwindJS)
module.exports = {
plugins: [
require('tailwindcss')(tailwindJS),
require('autoprefixer')
]
}
복사한 postcss.config.js
파일에서 TailwindJS 경로에 '..'
만 추가합니다. 이제 Storybook에서 webpack 설정을 하면 마무리됩니다.
// webpack.config.js
const path = require('path');
module.exports = async ({ config, mode }) => {
config.module.rules.push({
test: /\.scss$/,
loaders: ['style-loader', 'css-loader', 'sass-loader', 'postcss-loader'],
include: path.resolve(__dirname, '../'),
});
return config;
};
webpack 설정까지 마쳤습니다. 첫번째 Storybook의 story를 만들어봅니다. config.js
파일에서 각 컴포넌트와 같은 경로에 story를 위치하도록 하였습니다.
touch ./components/Logo.story.js
위 파일을 열고 아래의 내용으로 채워줍니다.
import { storiesOf } from '@storybook/vue';
import Logo from './Logo.vue'
storiesOf('Logo', module)
.add('Logo Component', () => ({
components: { Logo },
template: '<logo />',
}));
Logo.vue
컴포넌트를 열어 불러오는 것만으로 한개의 story를 만들었습니다. 자세한 내용은 Storybook의 문서를 보고 시도해보세요.
마지막으로 Storybook을 실행합니다. package.json
을 열어 아래 스크립트를 추가합니다.
{
"scripts": {
// ...
"storybook": "start-storybook -p 6006 -c .storybook"
/...
}
쉘을 열어 npm run storybook
명령어를 실행해 로고 컴포넌트가 Storybook에 정상적으로 등록되었는지 확인하세요.
Tailwindcss는 엘리먼트의 class 속성에 인라인 스타일을 넣는 것 과 유사한 방식으로 사용합니다.
<template>
<div class="bg-white mx-auto max-w-sm shadow-lg rounded-lg overflow-hidden">
<div class="sm:flex sm:items-center px-6 py-4">
<img class="block h-16 sm:h-24 rounded-full mx-auto mb-4 sm:mb-0 sm:mr-4 sm:ml-0" src="https://avatars2.githubusercontent.com/u/4323180?s=400&u=4962a4441fae9fba5f0f86456c6c506a21ffca4f&v=4" alt="">
<div class="text-center sm:text-left sm:flex-grow">
<div class="mb-4">
<p class="text-xl leading-tight">Adam Wathan</p>
<p class="text-sm leading-tight text-grey-dark">Developer at NothingWorks Inc.</p>
</div>
<div>
<button class="text-xs font-semibold rounded-full px-4 py-1 leading-normal bg-white border border-purple text-purple hover:bg-purple hover:text-white">Message</button>
</div>
</div>
</div>
</div>
</template>
위 컴포넌트를 만들고 Storybook에서 확인해보세요. Tailwindcss에서 사용하는 class를 Storybook에서도 사용할 수 있습니다.
Bootstrap, Foundation등의 CSS프레임워크는 PostCSS를 사용하지 않기 때문에 webpack이나 PostCSS설정을 추가로 할 필요는 없을 것 입니다. 만약 추가적으로 jQuery등의 설정을 한다면 이 문서의 webpack 설정 부분에서 해주시면됩니다.
Storybook webpack 설정 : https://storybook.js.org/docs/configurations/custom-webpack-config/