LoginSignup
5
2

More than 5 years have passed since last update.

React-NativeでSFCがHMRしてくれない問題を解決する

Posted at

そもそもの前提問題としてReact-NativeではHMRを有効化してもStateless Functional Component(以下SFC)に対してhot module replacement(以下HMR)してくれない問題がある。
https://github.com/facebook/react-native/issues/10991

上記のissueに記載あるが babel-plugin-functional-hmr を入れることでSFCに対してもHMRを有効化出来る。これで全て解決!と行けば良いのだが、、、

babel-plugin-functional-hmrを有効化した状態でjestのsnapshotテストをするとテストケースが失敗することがある

どういうケースで失敗するのか?
普段僕は業務でもプライベートでも styled-components を使用しています。
今回の場合、こういったエラーが発生しました。

locals[0] does not appear to be a `module` object with Hot Module replacement API enabled. You should disable react-transform-hmr in production by using `env` section in Babel configuration. See the example in README: https://github.com/gaearon/react-transform-hmr

      2 |
      3 | import React from 'react';
    > 4 | import { Container, BadgeText } from './style';

これは react-transform-hmr が有効化されているので発生しているので、 babel-plugin-functional-hmr を developmentだけで有効化すれば良いのがわかります。
しかし、 .babelrc に記述するだけだと 例えば NODE_ENV=test jest してもこのエラーを回避できませんでした。

解決方法

.babelrcではなく babel.config.jsにし、下記のように記述する

module.exports = api => {
  const env = api.cache(() => process.env.NODE_ENV);
  return {
    presets: ['module:metro-react-native-babel-preset'],
    plugins: [
      [
        'module-resolver',
        {
          root: ['./'],
          alias: {
            '@': './src'
          }
        }
      ]
    ],
    env: {
      development: {
        plugins: env === 'test' ? [] : ['functional-hmr']
      }
    }
  };
};

plugins 内は設定してなかったら特に何も記述しなくて良いと思います。
またこの書き方は自分の環境内で使っている形なので、 babel.config.js はfunctionにする、引数.cache を使う、 development以外では babel-plugin-functional-hmr を有効化しない。
これらを守るとSFCにHMRを有効化させつつ、 babel-plugin-functional-hmr によってjestでエラーが吐かなくなります。

汎用的なベストプラクティスがあれば編集リクエストください。

現場からは以上です。

5
2
0

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
5
2