じまろぐ

めめ

React + Typescriptプロジェクトでplugin-styled-componentsを使うときの設定

  • styled-components使ってる
  • env !== "production" のときにクラス名にファイル名が入るようにしたい
  • babel-plugin-styled-componentsがある
  • TypeScriptだとこのプラグインは効かない
    • ts-loaderでトランスパイルしてるから
  • storybookでも使いたい

という感じで、ts-loaderを使ってるのでTypeScriptプロジェクトの場合は typescript-plugin-styled-components を使う必要がある。babelでやってる場合は babel-plugin-styled-components で大丈夫なはず。

設定

webpack.config.js で ts-loaderのoptionを設定する。

const path = require("path");
const createStyledComponentsTransformer = require("typescript-plugin-styled-components")
  .default;
const styledComponentsTransformer = createStyledComponentsTransformer({
  displayName: process.env.NODE_ENV !== "production",
  getDisplayName(filename, bindingName) {
    // コンポーネントのパスがクラス名に入るように
    return path.relative(__dirname, filename);
  }
});

module.exports = {
  // 省略
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: "ts-loader",
        options: {
          onlyCompileBundledFiles: true,
          getCustomTransformers: () => ({
            before: [styledComponentsTransformer]
          })
        }
      }
    ]
  },
  // 省略
};

storybookで使う

"@storybook/preset-typescript" を使ってる前提

.storybook/main.js

const path = require('path');
const createStyledComponentsTransformer = require("typescript-plugin-styled-components")
  .default;
const styledComponentsTransformer = createStyledComponentsTransformer({
  getDisplayName(filename, bindingName) {
    // コンポーネントのパスがクラス名に入るように
    return path.relative(path.resolve(__dirname, "../") ,filename)
  }
});
module.exports = {
  stories: [
    '../src/**/*.stories.tsx'
  ],
  addons: ['@storybook/addon-actions/register','@storybook/addon-actions', {
    name: "@storybook/preset-typescript",
    options: {
      tsLoaderOptions: {
        transpileOnly: true,
        getCustomTransformers: () => ({
          before: [styledComponentsTransformer]
        })
      },
      include: /\.tsx?$/
    }
  }]
};

でクラス名にファイルのパスが入るようになった。