loading...
Cover image for storybook + tailwind + nuxt one webpack config

storybook + tailwind + nuxt one webpack config

f3ltron profile image florent giraud ・3 min read

At Vue Montreal we are using nuxt a lot.

Today i want to share with you something i feel it will help you as us. We wanted to add storybook to our project.

Everytime i had to create a webpack just for using storybook. And i faced a lot of bugs. And more when i wanted to use tailwind + postcss ^^.

So let's say you have a basic nuxt config with tailwind

So you should have:

  • '@nuxtjs/tailwindcss' in your buildModules
  • in your assets/css/tailwind.css
@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';

And that's all.

Now you want to implement storybook.
You want to add tailwind so postcss and not creating a new webpack or at least create another full configuration...

You have to create

.storybook/main.js
.storybook/preview.js

.storybook/preview.js

import Vue from 'vue'
import { configure } from '@storybook/vue'
import '@/assets/css/tailwind.css'

Vue.component('nuxt-link', {
  props:   ['to'],
  methods: {
    log() {
      action('link target')(this.to)
    },
  },
  template: '<a href="#" @click.prevent="log()"><slot>NuxtLink</slot></a>',
})

configure(require.context('../components', true, /\.stories\.js$/), module);

It's basic. I Added nuxt-link for not having some bug because storybook don't know about nuxt-link.
As you see i added import '@/assets/css/tailwind.css'.

and the most impostant.

.storybook/main.js

const { getWebpackConfig } = require('nuxt')

module.exports = {
    // `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.
    webpackFinal: async (sbWebpack, { configType }) => {

        const nuxtWebpack = await getWebpackConfig('client', {
            for: process.env.NODE_ENV === 'production' ? 'build' : 'dev'
        })

        const recomposedWebpackConfig = {
            mode: nuxtWebpack.mode,
            devtool: nuxtWebpack.devtool,
            entry: sbWebpack.entry,
            output: sbWebpack.output,
            bail: sbWebpack.bail,
            module: {
                rules: [
                    ...nuxtWebpack.module.rules.map(el => {
                        const reg = RegExp(el.test);
                        if (reg.test(".postcss") || reg.test(".css")) {
                            el.oneOf = el.oneOf.map(e => {
                                e.use.push({
                                    loader: 'postcss-loader',
                                    options: {
                                        ident: 'postcss',
                                        plugins: [
                                        require('tailwindcss')('./tailwind.config.js'),
                                        require('autoprefixer'),
                                        ],
                                    },
                                })
                                return e;
                            })
                        }
                        return el;
                    })
                ]
            },
            plugins: sbWebpack.plugins,
            resolve: {
                extensions: nuxtWebpack.resolve.extensions,
                modules: nuxtWebpack.resolve.modules,
                alias: {
                    ...nuxtWebpack.resolve.alias,
                    ...sbWebpack.resolve.alias,
                },
            },
            optimization: sbWebpack.optimization,
            performance: {
                ...sbWebpack.performance,
                ...nuxtWebpack.performance
            }
        }

        return recomposedWebpackConfig;
    },
};

The 'problem' here is you need some of storybook webpack and nuxt webpack. So i decided to recompose a webpack config
with storybook custom webpack.

And THIS. A new feature from nuxt that expose nuxt webpack config with getWebpackConfig. It return a promise and it's a valid webpack export as you can export promise now too INFO HERE.

The most important part for you here is:

module: {
 rules: [
  ...nuxtWebpack.module.rules.map(el => {
    const reg = RegExp(el.test);
    if (reg.test(".postcss") || reg.test(".css")) {
      el.oneOf = el.oneOf.map(e => {
       e.use.push({
        loader: 'postcss-loader',
        options: {
         ident: 'postcss',
         plugins: [
          require('tailwindcss')('./tailwind.config.js'),
          require('autoprefixer'),
         ],
        },
      })
      return e;
     })
    }
    return el;
   })
  ]
},

What you need to update are .postcss and .css rules.

And that's it! Now you should be able to write tailwind / postcss in your component with "ONE CONFIG" :).

This is my workaround. Maybe it's not the best so tell me in comments.

ps: An ISSUE in @nuxtjs/tailwind about adding support with storybook.

Posted on by:

Discussion

markdown guide
 

In case this would be useful to someone else, I got it working by manually configuring the source loader:

{
test: /.(stories|story).[tj]sx?$/,
loader: require.resolve('@storybook/source-loader'),
exclude: [/node_modules/],
enforce: 'pre',
}
github.com/storybookjs/storybook/b...

 

do you have a repo example you can share ? I am currently having the same bug you had i think ^^. Their docs are new and not so well documented on this...

Can tell us the version you are using too? Thank's :) Because there are some bugs with next version apparently

 

Hi Florent, after some issues I decided to keep two independent webpack configurations. Here you can check my implementation:
github.com/nonlinearcom/storybook-...

Can you describe what was your issue on it ? And thank's for the repo i will check

 

Hello manuel you mean this github.com/storybookjs/storybook/t... ? If yes i will try to apply those 3 addons soon to our project:

github.com/storybookjs/storybook/t...
github.com/storybookjs/storybook/t...
github.com/storybookjs/storybook/t...

You can follow me i will write an article soon about using storybook + chromatic too

 

Hi Florent, great article! it solved my nuxt / postcss configuration :)
In my case, the only issue left is that there is "no code available" message under the Docs tab... do you have any idea on how to fix that?
Thanks id advance!
Manuel

 

thank's :).

Yeah i am facing some issues with docs too. But working on it. github.com/vuemontreal/vuemontreal....

I can work with basic doc but it's not working well with mdx