embryo

エンジニアの備忘録

React+Typescriptでコンポーネント公開用のBoilerplateを作った

今日はReact製のコンポーネントを外部公開するための雛形を作成したのでその紹介です。 ソースは以下。

github.com

構成

Typescript

型が欲しいのでTypescriptを使用しています。普段も大体Typescriptで書いています。

Jest

単なるコンポーネントのテストが目的なのでシンプルなパッケージ構成で簡単にテストできる jest を使用しています。

Typescriptを設定する

テストも型安全に書きたいのでts-loaderを使用しています。package.jsonに以下の設定を追記します。

 "jest": {
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js"
    ],
    "transform": {
      "\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
    },
    "testRegex": "/__spec__/.*\\.(ts|tsx|js)$"
  }

レンダリング結果をテスト

Componentのレンダリング結果をテストするためにairbnb製の enzyme を使用しています React.TestUtilsでも問題ありませんがjest公式で説明されているためこちらを使用します。

GitHub - airbnb/enzyme: JavaScript Testing utilities for React

import Component from "../Component";
import * as React from "react";
import * as Enzyme from "enzyme";

describe("Component", () => {

  it("content", () => {

    // Render a component
    const component = Enzyme.shallow(<Component />);
    expect(component.text()).toEqual("Awesome component");

 });

});

Storybook

開発中の動作確認の他、StyleGuide生成のために storybook を使用しています。 他にも style-guidist, catalog など選定に上がりましたが、フレームワークとしてのルールやメンテの容易さから storybook を選定しました。

Typescriptを設定する

公式の説明通りにセットアップを済ませると、.storybook以下にファイルが生成されるのでカスタマイズしたい場合はファイルを編集します。

.storybook
├── config.js
└── webpack.config.js

私はes6で設定を記述したいのでwebpack.config.babel.jsを作成し、webpack.config.jsから読み込んでいます。実際の設定は以下のようになります。今回はts-loaderを追加し、Typescriptを使用できるようにしています。

import path from "path";
import genDefaultConfig from "@storybook/react/dist/server/config/defaults/webpack.config.js";

module.exports = function(baseConfig, env) {
  const config = genDefaultConfig(baseConfig, env);

  config.resolve.extensions.push(".ts", ".tsx");

  config.module.rules.push({
    test: /\.(ts|tsx)$/,
    include: [/stories/, /src/],
    loader: require.resolve("ts-loader")
  });

  return config;
};

Storyファイルを書く

stories配下にファイルを配置して、実際のデモを記述します。

import * as React from "react";

import { storiesOf } from "@storybook/react";
import { Component } from "../src/Component";

storiesOf("Components", module)
  .add("Awesome component", () => <Component />)

Storyファイルを読み込む

.storybook/config.jsを編集してファイルを追加します。UIや設定をカスタマイズしたい場合はオプションを設定します。

import { configure } from "@storybook/react";

const loadStories = () => {
  require("../stories/index.tsx");
}

configure(loadStories, module);

あとはnpm scriptにstorybookが追加されているので実行してブラウザで確認します。

参考