Get started: Vue3 + Typescript + Vite + Tailwindcss + Storybook

Get started: Vue3 + Typescript + Vite + Tailwindcss + Storybook

2023-03-25
4 min read

Setup Vite and Install storybook

First of all scaffolding your vite project.

shell
# NPM
npm create vite@latest
# Yarn
yarn create vite
# PNPM
pnpm create vite

Choose Vue and Typescript.

builder

Run following command to generate the skeleton in your project.

shell
npx sb init

This command is the simplest way to add a Storybook to your project. It will install peer dependencies and generate configs for a StoryBook.

After running the command, following directories should be created.

text
├── .storybook
│   ├── main.cjs
│   └── preview.cjs
├── src
│   ├── stories
│   │   ├── Button.jsx
│   │   ├── Button.stories.jsx
│   │   └── Introduction.stories.mdx
│   └── vite-env.d.ts

If you are using typescript, you are able to change extensions from cjs and jsx to .ts and tsx.

text
├── .storybook
│   ├── main.ts
│   └── preview.ts
├── src
│   ├── stories
│   │   ├── Button.tsx
│   │   ├── Button.stories.tsx
│   │   └── Introduction.stories.mdx    
│   └── vite-env.d.ts

You can find new commands in your package.json

text
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"

storybook will start a local development server with 6006 port number.

Run storybook commend to start a local development server

shell
# NPM
npm run storybook
# Yarn
yarn storybook
# PNPM
pnpm storybook``

Error handling

If you get Error: error:0308010C:digital envelope routines::unsupported error, when you run. You have to add SET NODE_OPTIONS=--openssl-legacy-provider option before you run start-storybook.

text
"storybook": "SET NODE_OPTIONS=--openssl-legacy-provider && start-storybook -p 6006",

Install tailwindcss

shell
npm install -D tailwindcss postcss autoprefixer
yarn add -D tailwindcss postcss autoprefixer
pnpm add -D tailwindcss postcss autoprefixer

Install tailwindcss and its peer dependencies

shell
npx tailwindcss init -p

Generate tailwind.config.cjs and postcss.config.cjs and add the paths in tailwind.config.cjs.

js
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./index.html",
    "./src/**/*.{js,ts,jsx,tsx,vue}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

Add the Tailwind directives to your CSS

css
@tailwind base;
@tailwind components;
@tailwind utilities;

Add Tailwindcss

Import Tailwind directives css file in .storybook/preview.cjs to use Tailwind

js
import '../src/style.css'

I added Tailwind directives css in ./src/styles.css, so I import with path. The path could be different with your project.

Create component and display it on Storybook.

First of all, create any component under ./src/components. In this article, I created CButton.vue. In case of confuse, I cleared all files. under ./src/stories.

Example Component

vue
<template>
  <button
    class="bg-blue-500 hover:bg-blue-700 text-white font-bold inline-flex capitalize rounded"
    :class="classes"
  >
    {{ label }}
  </button>
</template>
<script lang="ts">
export default {
  name: 'c-button'
}
</script>
<script setup lang="ts">
import { computed } from 'vue'

interface Props {
  label: string
  size?: 'sm' | 'md' | 'lg'
}

const props = withDefaults(defineProps<Props>(), {
  size: 'sm'
})
const emit = defineEmits(['click'])

const classes = computed(() => ({
  'py-1 px-2': props.size === 'sm',
  'py-2 px-4': props.size === 'md',
  'py-2 px-4 text-xl': props.size === 'lg',
}))
</script>

Create vue file named CButton.vue. Copy the code and paste it to CButton.vue.

Stories File

Create Storybook file under /src/stories. File name should include .stories.[ts|js|cjs]

typescript
import CButton from '../components/CButton.vue'
import { Meta, Story } from '@storybook/vue3'

interface Props {
  label: string
  size?: 'sm' | 'md' | 'lg'
}

export default {
  title: 'Example/Components/CButton',
  component: CButton,
  argTypes: {
    label: {
      type: 'string',
    },
    onClick: {},
    size: {
      control: { type: 'select' },
      options: ['sm', 'md', 'lg'],
    }
  },
} as Meta<Props>

const Template: Story<Props> = (args) => ({
  components: { CButton },
  setup() {
    return { args }
  },
  template: '<CButton v-bind="args" />',
})

export const CButtonLarge = Template.bind({})
CButtonLarge.args = {
  label: 'Large',
  size: 'lg'
}

export const CButtonMedium = Template.bind({})
CButtonMedium.args = {
  label: 'medium',
  size: 'md'
}

export const CButtonSmall = Template.bind({})
CButtonSmall.args = {
  label: 'small',
  size: 'sm'
}

Create a Storybook file named CButton.stories.ts. Copy the code and paste it to CButton.stories.ts.

Build

shell
npm run build-storybook
# Yarn
yarn build-storybook
# PNPM
pnpm build-storybook

After running the command, output will be in storybook-static under project root.

Error handling

If you get Error: error:0308010C:digital envelope routines::unsupported error, when you run build command . You have to add SET NODE_OPTIONS=--openssl-legacy-provider option before command just like you did for development.

text
"build-storybook": "SET NODE_OPTIONS=--openssl-legacy-provider && build-storybook",

Ref

Free open source project made by Youngjin