LoginSignup
29
24

More than 5 years have passed since last update.

React + Storybook + styled-componentsをTypeScriptで動かす

Last updated at Posted at 2018-06-14

設定するところが多く調べるところが多かったため、備忘録として書きます。

ツールのバージョン

@storybook/react

最新版を使いましょう。

"@storybook/react": "^4.0.0-alpha.9",

styled-components

自分がcssはstyled-componentsを使っていたので一応書いておきます。
これも最新版を使わないとエラーが発生しました。

"styled-components": "^3.3.2"

型定義ファイル

インストールしたものを抜粋します。

package.json
"devDependencies": {
    "@types/jest": "^23.0.2",
    "@types/react": "^16.3.17",
    "@types/react-dom": "^16.0.6",
    "@types/storybook__addon-actions": "^3.0.3",
    "@types/storybook__addon-links": "^3.3.1",
    "@types/storybook__addon-notes": "^3.3.1",
    "@types/storybook__addon-storyshots": "^3.4.2",
    "@types/storybook__react": "^3.0.7",
}

webpack.config.js

小さい構成なので以下のようになりました。

webpack.config.js
const path = require('path');
const env = process.env.NODE_ENV;

const config = {
    mode: env || 'development',
    target: 'node',
    entry: {
        index: [path.resolve(__dirname, 'src/index.js')],
    },
    output: {
        path: path.resolve(__dirname, './public/'),
        publicPath: './public/',
        filename: '[name].js',
    },
    module: {
        rules: [
            {
                test: /\.(ts|tsx)$/,
                loader: 'babel-loader!awesome-typescript-loader',
            },
        ],
    },
    resolve: {
        extensions: ['.ts', '.tsx'],
    },
};

module.exports = config;

storybook

storybook側も設定が必要です。

webpack

webpackの設定を追加します。

.storybook/webpack.config.js
const path = require("path");

module.exports = (baseConfig, env, defaultConfig) => {
    defaultConfig.module.rules.push({
        test: /\.(ts|tsx)$/,
        include: path.resolve(__dirname, "../src"),
        loader: require.resolve("awesome-typescript-loader")
    });

    // addon-storysource使うときだけ
    defaultConfig.module.rules.push({
        test: /\.stories\.jsx?$/,
        loaders: [
            {
                loader: require.resolve("@storybook/addon-storysource/loader"),
                options: { parser: "typescript" }
            }
        ],
        enforce: "pre"
    });

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

    return defaultConfig;
};

config.js

.ts.tsxの拡張子を持つファイルを対象にします。

.storybook/config.js
import React from 'react';
import { configure } from "@storybook/react";
const req = require.context("../src/Components", true, /.stories.(ts|tsx)$/);

function loadStories() {
    req.keys().forEach((filename) => req(filename));
}

configure(loadStories, module);

styled-components

テーマファイルを作成しつつ、モジュールをラップするようにしてTypeScriptに適用させます。
共通で使用するカラー変数などもここで設定することも可能です。

Theme/index.ts
import * as styledComponents from "styled-components";

export interface ThemeInterface {
    primaryColor: string;
}

export const Theme = {
    primaryColor: "#e9e9e9"
};

const {
    default: styled,
    css,
    injectGlobal,
    keyframes,
    ThemeProvider
} = styledComponents as styledComponents.ThemedStyledComponentsModule<ThemeInterface>;

export default styled;
export { css, injectGlobal, keyframes, ThemeProvider };

Component

実際のコンポーネントは以下のようになります。
ポイントはnode_modulesからstyled-componentsを直接読み込まず、上で作成したTypeScriptに適用させたものを読み込むところです。

Caption/index.tsx
import * as React from "react";
import styled from "../Theme";

interface CaptionInterface {
    children?: React.ReactChild;
}

const StyledCaption = styled.h1`
    margin: 0 0 12px 0;
    color: black;
    font-size: 2rem;
    font-weight: bold;
    line-height: 1.4;
`;
const Caption:React.SFC<CaptionInterface> = ({...props}) => <StyledCaption {...props} />;
export default Caption;

当然storybookも.tsxで作成します。

Caption/index.stories.tsx
import React from 'react';
import { storiesOf } from '@storybook/react';

import Caption from './index';

storiesOf('Atoms/Caption', module).add('default', () => <Caption>Caption is here!</Caption>);

おわり

多分これで動くと思います!
お役に立っていたら嬉しいです。

29
24
3

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
29
24