エンジニアの覚え書き

web系エンジニアの技術メモを主に投稿していきます。

postcss.config.jsに変数を渡す

babel7 + webpack4 + storybook4にバージョン上げる作業を頑張ったので、しばらくその辺の話を書いていく。

css-loaderが1.0.0からminimize optionを廃止されたため、代替手段としてcss-nanoを追加した。その際に、postcss.config.jsに変数を渡したくて、調べたら方法があったのでメモレベルで記事にする。

before

webpack.config.js の断片

          {
            loader: 'css-loader',
            options: {
              // CSS Loader https://github.com/webpack/css-loader
              importLoaders: 1,
              sourceMap: isDebug,
              // CSS Modules https://github.com/css-modules/css-modules
              modules: true,
              localIdentName: isDebug ? '[name]-[local]-[hash:base64:5]' : '[hash:base64:5]',
              // CSS Nano http://cssnano.co/options/
              // css-loader 1.0.0で廃止されたオプション
              minimize: !isDebug,
              discardComments: { removeAll: true },
            },
          },
          {
            loader: 'postcss-loader',
            options: {
              config: {
                path: './postcss.config.js',
              },
            },
          },

after

webpack.config.js の断片

          {
            loader: 'css-loader',
            options: {
              // CSS Loader https://github.com/webpack/css-loader
              importLoaders: 1,
              sourceMap: isDebug,
              // CSS Modules https://github.com/css-modules/css-modules
              modules: true,
              localIdentName: isDebug ? '[name]-[local]-[hash:base64:5]' : '[hash:base64:5]',
            },
          },
          {
            loader: 'postcss-loader',
            options: {
              config: {
                path: './postcss.config.js',
                ctx: {
                  isDebug,
                },
              },
            },
          },

postcss.config.js の断片

module.exports = ({ options }) => ({
  // The list of plugins for PostCSS
  // https://github.com/postcss/postcss
  plugins: [
    // ...略
    ...(!options.isDebug
      ? [
        require('cssnano')({
          preset: [
            'default',
            {
              discardComments: { removeAll: true },
            },
          ],
        }),
      ]
      : []),
  ],
});

公式ドキュメント

github.com

css-loaderのmodules optionを理解した

boilerplateのwebpackの設定をあまり理解せずに使っていると、新しく何かしようとした時にwebpack周りで困ることは(私にとっては)よくある話で、今回は困った結果、css-loaderのmodules optionを理解した。

今回理解したこと

CSS modulesではないcomponentをwebpackに組み込む場合、modules: falsecss-loaderを通さないといけない。文章にしてみると当たり前だけど、正しく理解してないと困ってしまう。

webpack.config.js

include, excludeを使って既存の設定とは別のloaderを通してあげれば良い。今回はreact-componentのrc-sliderを組み込んだ。

        test: /\.s?css$/,
        exclude: /node_modules\/rc-slider/,
        use: [
          {
            loader: 'isomorphic-style-loader',
          },
          {
            loader: 'css-loader',
            options: {
              // CSS Loader https://github.com/webpack/css-loader
              importLoaders: 1,
              sourceMap: isDebug,
              // CSS Modules https://github.com/css-modules/css-modules
              modules: true,
              localIdentName: isDebug ? '[name]-[local]-[hash:base64:5]' : '[hash:base64:5]',
              // CSS Nano http://cssnano.co/options/
              minimize: !isDebug,
              discardComments: { removeAll: true },
            },
          },
          {
            loader: 'postcss-loader',
            options: {
              config: {
                path: './postcss.config.js',
              },
            },
          },
        ],
      },
      {
        test: /\.s?css$/,
        include: /node_modules\/rc-slider/,
        use: [
          {
            loader: 'isomorphic-style-loader',
          },
          {
            loader: 'css-loader',
            options: {
              // CSS Loader https://github.com/webpack/css-loader
              importLoaders: 1,
              sourceMap: isDebug,
              // CSS Modules https://github.com/css-modules/css-modules
              modules: false,
              // CSS Nano http://cssnano.co/options/
              minimize: !isDebug,
              discardComments: { removeAll: true },
            },
          },
        ],
      },

webpackむずい。

ReactDOM.hydrateの仕様を少し理解した

reactjs.org

React expects that the rendered content is identical between the server and the client. It can patch up differences in text content, but you should treat mismatches as bugs and fix them. In development mode, React warns about mismatches during hydration. There are no guarantees that attribute differences will be patched up in case of mismatches. This is important for performance reasons because in most apps, mismatches are rare, and so validating all markup would be prohibitively expensive.

意訳すると、htmlの要素の差異は警告を出力して修正するが、htmlの属性の差異はパフォーマンスの都合で修正される保証はない、とのことらしい。 localStorageにtokenがあれば自動で認証して画面表示するようなページで、React16にバージョン上げてからレイアウト崩れる不具合はこれが原因だった(特定の要素のclassの値が期待通りにならなくて困っていた)。

以前の修正

client.js

リダイレクトする前にinnerHTMLを空にする方法(この修正だと一部の画面では不具合が修正されなかった)。

    if (route.redirect) {
      history.replace(route.redirect);
      // const container: Element = (document.getElementById('app'): any);
      ReactDOM.unmountComponentAtNode(container);
      container.innerHTML = '';
      return;
    }

今回の修正

SomeComponent

componentDidMountが実行されたタイミングでstateを変えてレンダリングする方法(これで修正できた)。

type StateTypes = {|
  isMounted: boolean,
|};
class SomeComponent extends React.Component<PropTypes, StateTypes> {
  constructor(props: PropTypes) {
    super(props);
    this.state = { isMounted: false };
  }

  componentDidMount() {
    this.setState({ isMounted: true });
  }

  render() {
    const { isMounted } = this.state;

    return isMounted ? (
      // レンダリングしたいコンポーネント
    ) : (
      // loadingとか表示する
    );
  }
}

schemaspyをdocker-composeで動かす

official imageでschemaspyを導入する方法

github.com

docker-compose.yml

  schemaspy:
    image: schemaspy/schemaspy
    volumes:
      - ./schemaspy/output:/output
      - ./schemaspy/config:/config
    container_name: "schemaspy_local"
    command: ["-configFile", "/config/schemaspy.properties"]
    links:
      - mysql
  nginx:
    image: nginx
    container_name: "nginx_for_schemaspy"
    ports:
      - "10080:80"
    volumes:
      - ./schemaspy/output:/usr/share/nginx/html:ro

schemaspy/config/schemaspy.properties

# type of database. Run with -dbhelp for details
schemaspy.t=mysql
# database properties: host, port number, name user, password
schemaspy.host=mysql
schemaspy.port=3306
schemaspy.db=sample
schemaspy.u=db_user
schemaspy.p=password
# db scheme for which generate diagrams
schemaspy.s=sample

docker-compose upで起動すると、schemaspy/output配下にschemaspyが生成したhtmlが出力され、http://localhost:10080でアクセスできる。