結局 Next (TypeScript) にStorybookを入れるには何が必要なの?
なんかググったらいろいろ出てきますが、どれを試してもうまくいかなかったので最小構成を探ってみました
あなたのNextプロジェクトを汚さずにStorybookを導入しよう!
手順
依存関係のインストール
yarn add --dev @storybook/react @storybook/preset-typescript @storybook/builder-webpack5 @storybook/manager-webpack5 webpack ts-loader css-loader babel-preset-react-app babel-plugin-react-require
追加するのは
-
@storybook/react
- これがなきゃ始まらないだろう…たぶん
-
@storybook/preset-typescript
- TypeScriptを解釈するためのプリセット
-
@storybook/builder-webpack5, @storybook/manager-webpack5
-
@storybook/preset-typescript
を動かすために必要なWebpack 5を導入するためのパッケージたち
-
-
webpack
- 上で散々導入の準備をしてきたWebpack本体
-
ts-loader
- これがあれば
babel-loader
は要りません
- これがあれば
-
css-loader
- CSS Modulesに対応するために必要
-
babel-preset-react-app
- たぶんbabelがJSXを解釈するために必要
-
babel-plugin-react-require
- Nextのコンポーネント内ではReactを明示的にインポートする必要がないのでそれに合わせるためのbabel-plugin
npm scriptの定義
これは厳密には必須ではありませんが、なにかしらscriptsに登録しないとStorybookの起動に不便なので、こんな感じの追記をおすすめします
{
"scripts": {
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook"
}
}
.babelrc をつくる
さっきインストールしたpresetとpluginをbabelに伝えます
{
"presets": [
"react-app"
],
"plugins": [
"react-require"
]
}
main.js をつくる
しばらく前には config.js
と呼ばれていたそうです (参考)
なんか .storybook/webpack.config.js
を作っても読んでもらえなかったので、webpack configはここに書いたほうが良さそうです
const path = require("path")
module.exports = {
stories: ['../stories/**/*.stories.tsx'], // どのstoryファイルを読み込むのか
addons: ['@storybook/preset-typescript'], // TypeScriptに対応するためのプリセット
core: {
builder: 'webpack5' // アドオンがWebpack 5を要求するのでこれを指定
},
webpackFinal: async (config) => {
config.module.rules = [
// デフォルトのrulesに入っているCSS用の設定が悪さをするのでお帰りいただく
...config.module.rules.filter(rule => rule.test.source !== (/\.css$/).source),
// css-loader を設定しなおす
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
config.resolve.alias = {
"@": path.resolve(__dirname, "..") // こっちは私の趣味です
}
return config
}
}
余談ですが、aliasの設定は
webpackFinal: async (config) => ({
...config,
resolve: {
alias: {
"@": path.resolve(__dirname, "..")
}
}
})
って書くのも読んでもらえなかったので、あんまり融通がきかないようです
rulesは読めるのになんでだろうね
おわりに
インターネットの海に浮かんでいるミスリードたちに阻まれながら、私はここにたどり着くために今日1日を費やしてしまいました
悩んでいるあなたを救えたのなら私も苦労した甲斐があったというものです
なにか改善点などアドバイスがあればコメントいただけるとうれしいです
では、良いStorybookライフを!
2020/10/16 追記
CSS ModulesでインポートしていたclassNameがundefinedになっていることに気付いたので調査
依存関係に css-loader
が必要になりました
それに伴って main.js も書き換わっています
2022/04/01 追記
久しぶりに触ったらTypeScriptがうまく解釈されず、devDependencies
が4つほど増えることになりました
今回変更分は、TypeScript用のPresetの追加と、それがWebpack 5に依存しているためインストールとバンドラを指定する設定の追加です
なので、今後のアプデでWebpack 5対応がされれば不要になるかもしれません
Discussion