Using Storybook with Quasar
Tags: storybook, quasar, vue
Published: 2020-02-08 04:13:29

---
title: Using Storybook with Quasar
published: true
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/a95qtwi8c3vstgged5sx.png
description: Installing Storybook to show your components built with Quasar
tags: storybook, quasar, vue
---

Storybook is a tool to develop bulletproof components faster with a catalog of your components isolated into sections with your use cases implemented, showing off their appearance, behavior and functionalities with a lot of tools to easily communicate front end engineers with designers, UX and UI experts and the PO. You can develop the component isolated just like Sketch does to design them.

To explain how to integrate them I'll create a simple Quasar application with the `@quasar/cli` command `quasar create`:

```bash
$ quasar create storybook-quasar
```

And proceed to use the defaults as this is just an example. I advice using yarn as the package manager. I'll use yarn as the package manager of this example.

![bootstrapping quasar application](https://dev-to-uploads.s3.amazonaws.com/i/4wixna804vi3mw6fbc19.png)

Navigate to the freshly created directory.

```bash
$ cd storybook-quasar
```

And lets integrate Storybook into our Quasar project.

But there's a catch, at the time of this writing, those two have a little issue when installed together: they use different versions of `core-js`.

The issue is Storybook uses `core-js@3` and Quasar still uses `core-js@2` and those two have breaking changes, so, as Storybook have explicit internal dependency on the `core-js@3` and will not be affected by the upper scope `core-js` version, install `core-js@2` to be available for Quasar:

```bash
$ yarn add --dev core-js@^2.0.0
```

And you should be greeted this perfect install message.

![installing core-js version 2 package as a dev dependency with yarn](https://dev-to-uploads.s3.amazonaws.com/i/oq0lylor72o41cifjfks.png)

Then you can proceed to add Storybook as suggested on the useful [vue guide on the storybookjs docs page](https://storybook.js.org/docs/guides/guide-vue/).

```bash
$ npx -p @storybook/cli sb init --type vue
```

And you should see a LOT of warnings and a HUGE list of installed dependencies of dependencies.

![adding storybook on the quasar application](https://dev-to-uploads.s3.amazonaws.com/i/bu0r97d6px94rbqhni1o.png)

And as the storybook installer says: now you can `yarn storybook` your way into it.

```bash
$ yarn storybook
```

And after some compiling, loading and detecting it should open `http://localhost:6006` on your browser.

![storybook default landing welcome story](https://dev-to-uploads.s3.amazonaws.com/i/q6osm7ma513bdwpx9q6v.png)

And it even comes with a button simple example story to show off:

![default button component story example](https://dev-to-uploads.s3.amazonaws.com/i/bt4xz4ptgrf000yyu8w8.png)

But as you will notice, quasar style and functionality isn't present on the stories. We need to import Quasar into our stories context to make it work, as Quasar can't run the stories and inject all its magic.

So open up your editor of preference (mine is VSCode) and let's change Storybook settings to add Quasar into it.

As the same settings will be shared between the `./quasar.conf.js` file and the `./.storybook/main.js` file I strongly suggest you extract the common logic to separated files to be imported in those files.

So I've created a `./webpack-config.js` file exporting a webpack configuration function:

```js
// ./webpack-config.js

module.exports = cfg => {
  cfg.module.rules.push({
    enforce: 'pre',
    test: /\.(js|vue)$/,
    loader: 'eslint-loader',
    exclude: /node_modules/,
    options: {
      formatter: require('eslint').CLIEngine.getFormatter('stylish')
    }
  })
}
```

And imported it into the `./.storybook/main.js` file as this:

```js
// ./.storybook/main.js

const webpackFinal = require('../webpack-config.js');

module.exports = {
  stories: ['../stories/**/*.stories.js'],
  addons: ['@storybook/addon-actions', '@storybook/addon-links'],
  webpackFinal
};
```

In Storybook config object `webpackFinal` is the name of the function passed to extend webpack functionality through its configuration. Similar changes should be made into the `./quasar.conf.js` file. Import the function on the top and change the `extendWebpack` on the line 69, inside the `build` property.

```js
// ./quasar.conf.js

const extendWebpack = require('../webpack-config.js')

[...]
```

Your `./quasar.conf.js` changes should look like this:

![quasar conf file changes to use webpack config function](https://dev-to-uploads.s3.amazonaws.com/i/cw6febe8ivszyugi6h44.png)

These changes will make it possible for Storybook to load vue and js files without errors. If you use sass or other style preprocessor, add it into the webpack-config like this:

```js
// ./webpack-config.js
const path = require('path')

module.exports = cfg => {
  cfg.module.rules.push({
    enforce: 'pre',
    test: /\.(js|vue)$/,
    loader: 'eslint-loader',
    exclude: /node_modules/,
    options: {
      formatter: require('eslint')
        .CLIEngine
        .getFormatter('stylish')
    }
  })
  cfg.module.rules.push({
    test: /\.s(c|a)ss$/,
    use: ['css-loader', 'sass-loader'],
    include: path.resolve(__dirname, '../'),
  })
  return cfg
}
```

And if you use aliases on your components, would be better to extract that list too to a function on a `./aliases.js` file:

```js
const { resolve } = require('path')

const resolveAlias = (rootRelativePath, aliases) => {
  return (accumulator, name) => {
    const aliasPath = aliases[name]

    const resolvedPath = resolve(...rootRelativePath, ...aliasPath)

    return {
      ...accumulator,
      [name]: resolvedPath
    }
  }
}

const aliases = {
  '@': ['src'],
  src: ['src'],
  components: ['src', 'components'],
  tools: ['src', 'tools'],
  mixins: ['src', 'mixins'],
  store: ['src', 'store']
}

module.exports = (...dir) => Object.keys(aliases)
  .reduce(resolveAlias(dir, aliases), {})
```

And then we'll have our aliases in Quasar and Storybook. After that, you'll need to import Quasar framework features in a newly created file `./.storybook/preview.js`. This file will import Quasar files to inject in Storybook preview iframes.

```js
// ./.storybook/preview.js

// Setup context for Storybook here
import 'quasar/dist/quasar.min.css'
import '@quasar/extras/roboto-font/roboto-font.css'
import '@quasar/extras/material-icons/material-icons.css'
import '@quasar/extras/material-icons-outlined/material-icons-outlined.css'

import 'quasar/dist/quasar.css'
// import 'src/css/app.scss' // if you have an app.scss|sass|styl main file

import Vue from 'vue';
import Quasar from 'quasar';

Vue.use(Quasar, { config: {}, directives: {} });

// run needed boot plugins files down here like `bootFile({ Vue })`

```

Then restart your storybook instance just to be sure it will reload with everything with: `yarn storybook` and check if everything is running properly. And after it opens in your browser you'll notice Quasar styles took over.

![Quasar styles took over storybook default example stories](https://dev-to-uploads.s3.amazonaws.com/i/ejyb31xg92w8qx3hxa4i.png)

And now you can create a new story to develop your brand new component with Quasar magic:

```js
// ./stories/2-Quasar.stories.js

import { QLayout, QPageContainer, QPage, QSelect, QBtn } from 'quasar'

export default {
  title: 'Quasar'
}

export const Components = () => ({
  title: 'QuasarComponents',
  components: { QLayout, QPageContainer, QPage, QSelect, QBtn },
  template: `<q-layout>
    <q-page-container>
      <q-page class="full-height full-width justify-center items-center q-pa-xl">
        <div class="col-auto">
          <q-input v-model="name" label="Full name" />
          <q-select v-model="role" :options="options" label="User Role" />
        </div>
      </q-page>
    </q-page-container>
  </q-layout>`,
  data () {
    return {
      name: null,
      role: 'User',
      options: ['Admin', 'Supervisor', 'User']
    }
  }
})
```

You should see this component being rendered with Quasar components and its marvelous style.

![quasar story running on storybook](https://dev-to-uploads.s3.amazonaws.com/i/9i5359a86bha3mlv3xpk.png)

Hope this little guide could help you. The generated code is available at the [yemolai/storybook-quasar repo](https://github.com/Yemolai/storybook-quasar) on Github. Go check it out. See ya.