12
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

React + TypeScriptのアプリケーションにStorybook + Storyshotsを導入する

Last updated at Posted at 2020-01-13

React + TypeScriptのアプリケーションの環境を構築していて、StorybookとStoryshotsの設定でハマったところのメモ。

環境

React 16.12.0
typescript 3.7.4
webpack 4.41.5
storybook 5.2.8

最初create-react-appでやっていたが、storyshotの導入でwebpackやjestの設定を変える必要が出てきたので、使わないで構築し直した。

#storybookの導入

セットアップ

package.json

devDependenciesに以下を追加してインストール

package.json
    "@storybook/addon-actions": "5.2.8",
    "@storybook/addon-links": "5.2.8",
    "@storybook/addons": "5.2.8",
    "@storybook/preset-typescript": "1.2.0",
    "@storybook/react": "5.2.8",

scriptsにスクリプトを追加

package.json
    "storybook": "start-storybook -p 6006",

/.storybook/config.jsを追加

/.storybook/config.js
import { configure } from '@storybook/react';

const req = require.context('../src/', true, /\.stories\.(?:js|ts)x?$/);
configure(req, module);

/.storybook/webpack.config.js を追加

ストーリーをTypeScriptで書くには、 /.storybook/ 内にwebpack.config.jsを追加する。

アプリケーションのwebpack設定を引き継ぎたい場合は
https://storybook.js.org/docs/configurations/custom-webpack-config/#using-your-existing-config
のように書くと短く書ける。

/webpack.config.js
  resolve: {
    modules: ['src', 'node_modules'],
    extensions: ['.ts', '.tsx', '.js'],
  },

この辺の設定も引き継がないと、import文のpath解決がうまく行かなくてちょっとハマった。
stories.tsx内でimport文でエラーになってしまう。

SomeComponent.stories.tsx
import OtherComponent from 'components/OtherComponent'; // モジュールのrootに指定した`src`がmodulesに設定されてないと Cannot find module
import AppHeader from '..'; //同階層のindex.tsxをインポート。extensionsにtsxが設定されていないと、Can't resolve '..'

なので
/.storybook/webpack.config.js はこのようになった。

/.storybook/webpack.config.js
const path = require('path');
// your app's webpack.config.js
const custom = require('../webpack.config.js');

module.exports = async ({ config, mode }) => {
  return {
    ...config,
    resolve: { ...config.resolve, ...custom.resolve },
    module: { ...config.module, rules: custom.module.rules }
  };
};

Storyshotsの導入

require-context-hookの設定

セットアップは
https://storybook.js.org/docs/testing/structural-testing/#using-storyshots
の通りだが、

require.context

の部分でエラーが出てしまうので、require-context-hookの設定をする。

devDependenciesに追加するのはこの辺

package.json
    "jest": "24.9.0",
    "react-test-renderer": "16.12.0",
    "@storybook/addon-storyshots": "5.2.8",
    "@types/jest": "24.0.25",
    "babel-plugin-require-context-hook": "1.0.0",

.babelrcにテスト用の設定を追加

  "env": {
    "test": {
      "plugins": [
        "require-context-hook"
      ]
    }
  }

/.storybook/config.js のrequire.contextの行の前に以下を足す。

/.storybook/config.js
if (process.env.NODE_ENV === 'test') {
  require('babel-plugin-require-context-hook/register')();
}

【追記】 storybook 5.3.1 にアップデートしたらrequire.contextを使わない記述になっていたので、ここの設定は不要っぽい :innocent:

cssや画像のインポートでのエラーを解決する

ストーリーの中でcssや画像をインポートしていると、storyshotsの実行時にエラーが出る。

Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

https://jestjs.io/docs/en/webpack#handling-static-assets
この通りにmoduleNameMapperを使用して解決できる。

スナップショットファイルをストーリーごとに分ける

デフォルトでは全てのストーリーのスナップショットが1ファイルに書きだされる。
スナップショットはストーリーごとに分かれた方が圧倒的に差分が見やすいので、分けたい。
そこでmultiSnapshotWithOptionsというオプションを指定する。
https://github.com/storybookjs/storybook/tree/master/addons/storyshots/storyshots-core#multisnapshotwithoptionsoptions

Storyshots.test.jsをこのように書き換える。

Storyshots.test.js
import initStoryshots, {
  multiSnapshotWithOptions,
} from '@storybook/addon-storyshots';

initStoryshots({
  test: multiSnapshotWithOptions(),
});

jestのconfigにはtransformの設定をする。

    "transform": {
      "^.+\\.stories\\.tsx$": "@storybook/addon-storyshots/injectFileName",
      "^.+\\.jsx?$": "babel-jest",
      ".+\\.tsx?$": "ts-jest"
    }

これで、各ストーリーのフォルダにスナップショットが作成される。 :thumbsup:

12
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?