Open11
Inertia.js + tailwindCSS + Vue3 に Storybookを導入する
まずは、以下のサイトを見て大まかな概要を掴む
お決まりのコマンドでStorybookのセットアップ
結構時間かかる(2~3分)
npx sb init
ありえないくらいhas unmet peer dependency
のWarningが出るが一旦放置
↑なぜかCloseされているが、まだ解決してない模様
warning "@storybook/addon-actions > @storybook/addons@6.5.15" has unmet peer dependency "react@^16.8.0 || ^17.0.0 || ^18.0.0".
warning "@storybook/addon-actions > @storybook/addons@6.5.15" has unmet peer dependency "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0".
warning "@storybook/addon-actions > @storybook/api@6.5.15" has unmet peer dependency "react@^16.8.0 || ^17.0.0 || ^18.0.0".
.
. 【中略】
.
warning "@storybook/manager-webpack5 > @storybook/core-client@6.5.15" has unmet peer dependency "react@^16.8.0 || ^17.0.0 || ^18.0.0".
warning "@storybook/manager-webpack5 > @storybook/core-client@6.5.15" has unmet peer dependency "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0".
warning "@storybook/manager-webpack5 > @storybook/ui@6.5.15" has unmet peer dependency "react@^16.8.0 || ^17.0.0 || ^18.0.0".
warning "@storybook/manager-webpack5 > @storybook/ui@6.5.15" has unmet peer dependency "react-dom@^16.8.0 || ^17.0.0 || ^18.0.0".
warning "@storybook/vue3 > vue-docgen-loader > jscodeshift@0.13.1" has unmet peer dependency "@babel/preset-env@^7.1.6".
Storybook用のESLintプラグインを入れるかどうか
eslint使っているので、yesを選択
✔ Do you want to run the 'eslintPlugin' migration on your project? … yes
ESLintの設定ファイルにプラグインを追加
eslintrc.yml
extends:
- 'plugin:vue/vue3-essential'
- 'eslint:recommended'
- '@vue/typescript/recommended'
+ - 'plugin:storybook/recommended'
- 'prettier'
諸々のインストールが終わったら以下コマンドでStorybookを起動
yarn storybook
Storybookは、デフォルトでPostCSS7を利用する
しかし、tailwindcssはPostCSS8で動いているので、PostCSS8を利用するように別途設定する必要がある
まずは、Addonを1つインストール
yarn add -D @storybook/addon-postcss
.storybook/main.jsに追加したAddonを追記
main.js
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
+ {
+ name: '@storybook/addon-postcss',
+ options: {
+ postcssLoaderOptions: {
+ implementation: require('postcss'),
+ },
+ },
+. },
],
.storybook/preview.jsにtailwindCSSのファイルパスをimport
preivew.js
+ import '../resources/css/app.css';
inertia.jsでは、propsを取得するのにusePage()関数を使う
usePageはReadonlyなので、直接モック関数に書き換えるのはベストではない。
しかし、@ts-ignore
を使うと一応動くのでこれで行く
もし、他の良い方法あれば教えてください。
import * as InertiaVue from '@inertiajs/inertia-vue3';
setup() {
// @ts-ignore
InertiaVue.usePage = jest.fn().mockImplementationOnce(() => {
return args;
});
return { args };
},
ziggy.jsを使っているので、window.route
関数のモックを用意する必要がある
エラー内容
Uncaught TypeError: window.route is not a function
モック化
index.stories.ts
import { jest } from '@storybook/jest';
declare global {
var route: typeof jest.mocked;
}
// has(), current()関数も必要なのでモックする
window.route = jest.fn().mockImplementation(() => {
return {
has: jest.fn(),
current: jest.fn().mockImplementation(() => {
return 'my-course';
}),
};
});
関数のモック化には、@storybook/jest
を使う
jest.mock()
が使えないなど制約はあるが、ほとんどの場合は、これでいけそう
SCSSを使っているコンポーネントのStoryを作ろうとしたら下記のエラーが出た
ModuleParseError: Module parse failed: Unexpected token (2:43)
File was processed with these loaders:
* ./node_modules/@storybook/vue3/node_modules/vue-docgen-loader/lib/index.js
* ./node_modules/@storybook/vue3/node_modules/vue-docgen-loader/lib/index.js
* ./node_modules/@storybook/vue3/node_modules/vue-loader/dist/index.js
You may need an additional loader to handle the result of these loaders.
.
.
中略
.
.
WARN Broken build, fix the error above.
WARN You may need to refresh the browser.
解決策
.storybook/main.jsに下記の記述が必要
.storybook/main.js
+const path = require('path');
module.exports = {
stories: ['../stories/**/*.stories.mdx', '../stories/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/addon-interactions',
{
name: '@storybook/addon-postcss',
options: {
postcssLoaderOptions: {
implementation: require('postcss'),
},
},
},
],
framework: '@storybook/vue3',
core: {
builder: '@storybook/builder-webpack5',
},
+ webpackFinal: async (config) => {
+ config.module.rules.push({
+ test: /\.scss$/,
+ use: ['style-loader', 'css-loader', 'sass-loader'],
+ include: path.resolve(__dirname, '../'),
+ });
+ return config;
+ },
};
参考資料
Ziggy-jsのroute関数を使っているコンポーネントのStory内で以下のエラーに遭遇
<!-- 例 -->
<Button :href="route('top')" primary quick>コース詳細</Button>
_ctx.route is not a function
以下の記述をpreview.jsに追加することで解決
import { app } from '@storybook/vue3';
const route = (route) => {
return '#';
};
app.mixin({ methods: { route } });