StoryBookを開発プロジェクトへ導入した際にはまった点

355
NO IMAGE

作成したコンポーネントのカタログ化、マニュアル替わり、テスト作成などを目的に、プロジェクトにてStoryBook[1]が導入された。上手く使って開発効率を上げていきたいところである。

プロジェクトのメンバーは誰もStoryBookを使ったことがなかった。
手始めに、一つのコンポーネント(保存用のボタン)をサンプルで表示できるところまで環境が整えられた。これであとは同じようにコンポーネントを追加していけば、カタログは完成できるだろうと考えていた。

次に、コンポーネントの改修とテストなどを実施してみようとなったのだが、ここで、2点ほどはまったので、備忘録も兼ねてブログに記載しておく。

Mockを作らないと動かなかった

Vue.js+Vuex+Typescriptのプロジェクトで、VuexのStoreにアクセスしているコンポーネントに関しては、Storeのモックを用意してテストデータを参照したりしないと使えないことは認識していた。
そのため、初めはAtomic Design[2]でいうところの、AtomやMoleculesだけを対象にしていく想定であった。
1つ目の『保存用のボタン』は問題無く動いていたのだが、二つ目に対象とした『ラベル付きテキストボックス』というコンポーネントにて、下記のようなエラーが発生した。

Module not found: Error: Can't resolve 'tls' in ...
Module not found: Error: Can't resolve 'fs' in ...
Module not found: Error: Can't resolve 'net' in ...

原因としては、『ラベル付きテストボックス』が参照しているモジュール内で上記の機能を必要としていたためで、実際にコンポーネント自体は、これら機能は使ってはいないという状況であった。

Googleで回避策を検索してみたところ、

  1. WebpackのConfigで、下記のようにempty定義してしまえばよい。

    module.exports = {
    node: {
    console: 'mock',
    fs: 'empty',
    net: 'empty',
    tls: 'empty'
    }
    };
  2. Mockを定義してMockを参照するように定義すればよい。

実際呼び出されるわけでもないし、2は大げさかな、1で良いなら楽そうだ1を選択したのだが、判断ミスだった。
いくつかのサイトを参考に何通りか設定をしてみたが、一向に解決せず、Mockを定義したらさくっと解決した。T_T

main.jsのmodule.exportsに下記のような感じで追記することで、エラーを回避できた。

const path = require('path')
const rootPath = path.resolve(__dirname, '../src')

module.exports = {
  webpackFinal: async (config, { configType }) => {
    config.resolve.alias = {
      ...config.resolve.alias,
      'fs': path.resolve(__dirname, 'fsMock.js'),
      'net': path.resolve(__dirname, 'netMock.js'),
      'tls': path.resolve(__dirname, 'tlsMock.js')
    };
    return config;
  }
}

SCSSが読み込まれていなかった

Mockを作ったことで、ブラウザに表示され、イベントやPropの変更など確認できて、作業完了と思ったところで、SCSSで定義したスタイルが反映されていないことに気づいた。

最終的には、下記のページを参考にした設定で解決したが、こちらも別ページを参考に試行錯誤して遠回りをしてしまった。
[Extending Storybook’s webpack config](https://storybook.js.org/docs/react/configure/webpack#extending-storybooks-webpack-config "Extending Storybook’s webpack config")

  css: {
    loaderOptions: {
      scss: {
        prependData: '@import "~@../src/scss/bootstrap-application.scss";'
      }
    }
  },
  webpackFinal: async (config, { configType }) => {
    config.resolve.alias['@'] = rootPath
    config.resolve.alias['~'] = rootPath  

    config.module.rules.push({
      test: /\.scss$/,
      use: ['style-loader', 'css-loader', 'sass-loader'],
      include: path.resolve(__dirname, '../')
    });