エンジニアの覚え書き

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

CSSのcursorプロパティを知らなかったので調べる

CSSは人のコードから拝借して実装することが多いので、CSSのプロパティを詳しく理解せず使っていることがよくある。その辺を解消するために、最近使ったcursorプロパティを調べたメモ。

cursorプロパティの値

/* キーワード値でカーソルの形を指定できる */
cursor: wait;
/ * カーソルの形は画像でも指定できる。URLが解決できなかった場合のフォールバックを指定する */
cursor: url("hoge.svg") url("fuga.png"), progress;
/* x, yでカーソルのクリック座標の位置を指定できる。カーソルの左上が基準座標。 */
cursor: url("hoge.svg") 3 3, auto;

参考

Babel7にバージョンアップ時に辿り着いたissueとworkaroundな対応メモ

Babel7にバージョンアップした際に、あれこれ調べてworkaroundな対応を行ったメモ。

storybook

regeneratorRuntime is not definedというエラーになるので、addons.jsconfig.js@babel/polyfillをimportするようにした。

github.com

※issueの内容自体はbabel7と関係ないけど、これで上手くいったので引用。

// .storybook/addons.js, .storybook/config.js
import '@babel/polyfill';

lint

TypeError: Cannot read property 'range' of nullになるので、eslintの設定を.eslintrcに切出しして、一時的にindenttemplate-curly-spacingをoffにした。

github.com github.com

    "rules": {
        "template-curly-spacing": "off",
        "indent": "off",
    }

build + jest

jest側はbabel.config.jsに設定を切り出ししないとbuildに失敗するが、babel-node側ではbabel.config.jsを参照してくれない場合があるため(dockerでbabel-node build的な処理を行った場合に発生した)、babel.config.jsを追加してpackage.jsonの設定を参照するようにした。

github.com

// babel.config.js
const pkg = require('./package.json');

module.exports = {
  presets: pkg.babel.presets,
  env: pkg.babel.env,
  plugins: pkg.babel.plugins,
};

flexboxについてのメモ

毎回chromeのdevtoolsで期待した見た目になるように試行錯誤しつつプロパティ設定していて時間を取られていたので、調べてメモ書きしておく。主軸の概念とか知らなかったので想定より勉強になった(知識が穴だらけで悲しい)。

参考

これを読んでおけばOK。

developer.mozilla.org

プロパティについて

  • flex-direction…主軸の向きと方向を指定
    • flex-direction: row:の場合、主軸は水平(→)
    • flex-direction: column:の場合、主軸は垂直(↓)
  • justify-content…主軸に沿った向きのレイアウトを指定
  • align-items…主軸に直行した向きのレイアウトを指定

Babel7のpolyfillのこれまでと違う点のメモ

babel7から@babel/polyfillにproposal polyfill(stage-3以下のpolyfill)が含まれなくなり、core-jsからのimportを個別に行う必要があると知ったのでメモしておく。

babeljs.io

import "core-js/fn/array/flatMap";の様に使っているものだけ個別にimportしてもよいが、core-js/stage配下にstage-xのpolyfillをまとめたものが配置されているので、これを使うと楽。

例えばwebpack.config.jsで使う

  entry: {
    client: ['@babel/polyfill', 'core-js/stage/2', './src/clientLoader.js'],
  },

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とか表示する
    );
  }
}