storybook + tailwind + nuxtでstorybookの設定を行う
「storybook + tailwind + nuxt one webpack config」を参考に「storybook + tailwind + nuxt」の環境構築を行ったときのメモです。
使用している技術
- Nuxt.js
- Vue.js
- HTML
- JavaScript(not TypeScript)
- Scss
- tailwindcss
バージョン
メインで使用しているもののバージョンのみ記載
- "nuxt": "^2.13.0"
- "@nuxtjs/tailwindcss": "^1.0.0"
- "@storybook/vue": "^6.0.21"
手順
基本的なstorybookの使用方法について以下のリンクを参考に行ってください。
1. assets/css/tailwind.css
にtailwindcssの内容を記載
@import 'tailwindcss/base'; @import 'tailwindcss/components'; @import 'tailwindcss/utilities';
2. storybookの設定ファイル作成
.storybook/main.js .storybook/preview.js
の2つのファイルを作成。
.storybook/main.js
const { resolve } = require("path"); const { getWebpackConfig } = require("nuxt"); module.exports = { // componentsの配下にしたい場合は、 // stories: ['../components/**/*.stories.js'], // のように記載 stories: ["../stories/**/*.stories.js"], // `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); // 拡張子が「.postcss」か「.css」の時 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; }); } // 拡張子が「.sass」か「.scss」の時(基本scssのみで良いが念のためsassも記載) if (reg.test(".sass") || reg.test(".scss")) { el.oneOf = el.oneOf.map((e) => { e.use.push( { loader: "postcss-loader", options: { ident: "postcss", plugins: [ require("tailwindcss")("./tailwind.config.js"), require("autoprefixer"), ], }, }, { loader: "sass-loader", }, // ここでscssの変数などの変換を行う { loader: "sass-resources-loader", options: { resources: ["./assets/scss/variable.scss"], include: resolve(__dirname, "../"), }, } ); 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; }, };
.storybook/preview.js
// tailwindの読み込み import '~/assets/css/tailwind.css'; // グローバルのscssファイル import '~/assets/scss/base.scss';
storybookの実行
$ npm run storybook // or yarn storybook
でstorybookを起動させることでstorybookを実行することができます。
対応したこと
1. scss上にtailwindのcssを追加していたため、scss + postcssのビルドで問題なく動くように設定
既存のvueファイルが
<template> <p class=hogeFuga>テキスト</p> </template> <script> export default { // 何かの処理 } </script> <style lang="scss" scoped> .hogeFuga { @apply font-bold text-left mb-5 mt-10; } </style>
のような感じでscss上にpostcssの記載が行われていたため、.storybook/main.js
に「scssを変換 →tailwindcssの変換を行う」
.storybook/main.js
(一部抜粋)
if (reg.test(".sass") || reg.test(".scss")) { el.oneOf = el.oneOf.map((e) => { e.use.push( { loader: "postcss-loader", options: { ident: "postcss", plugins: [ require("tailwindcss")("./tailwind.config.js"), require("autoprefixer"), ], }, }, { loader: "sass-loader", } ); return e; }); }
既存のscssファイルの読み込み(グローバルscss, scss変数の使用)
グローバルscssファイルの読み込み
.storybook/preview.js
に、読み込みを行いたいscssファイルを記載
.storybook/preview.js
(一部抜粋)
// グローバルのscssファイル import '~/assets/scss/base.scss';
scssの変数ファイルの読み込み
sass-resources-loaderのloaderを.storybook/main.js
に記載
.storybook/main.js
(一部抜粋)
if (reg.test(".sass") || reg.test(".scss")) { el.oneOf = el.oneOf.map((e) => { e.use.push( { loader: "sass-loader", }, { loader: "sass-resources-loader", options: { // ここに読み込みを行いたいscssファイルを記載 resources: ["./assets/scss/variable.scss"], include: resolve(__dirname, "../"), }, } ); return e; }); }
最後に
storybook v6に上げる方法についても以下のリンクに上げる方法がありますので、ぜひ参考にしてください。