Reactをv16に上げるために行ったこと

去年の9月、Reactのv16がリリースされた。

自分も、15.xからバージョンアップする機会があった。

破壊的変更もいくつかあるが以前からアナウンスされていたし、あまり難しくはないはず。
何より、公式が丁寧なドキュメントやツールを用意しているから、それを使えばハマりどころはないと思う。

とはいえせっかく作業したので、記録しておく。

自分が行ったのは、廃止になったReact.PropTypesの対応、MatとSetのPolyfillの導入、Enzymeのバージョンアップ、など。

React.PropTypes

v16からReact.PropTypesが別パッケージになり本体から削除されたので、使っている場合は別パッケージであるprop-typesに置き換える必要がある。

jscodeshiftreact-codemodを使えば、簡単に置き換えることが出来る。

使用方法は以下の通り。

  1. $ npm install -g jscodeshift
  2. https://github.com/reactjs/react-codemod.gitをクローンしてくる
  3. 上記リポジトリ$ npm i
  4. $ jscodeshift -t react-codemod/transforms/React-PropTypes-to-prop-types.js <対象となるディレクトリやファイルのパス>

対象となるコードのなかでFlowを使っていると、4のコマンドを実行した際にTransformation errorになってしまうことがある。
そのときはコマンドの末尾に--parser=flowとつけて実行すればよい。

どうやらPropTypesの置き換えだけを行うわけではなく、よかれと思ってLintのようにインデントのずれを直したりするので、一応、意図しない差分が含まれていないかチェックしたほうがいい。

もちろん、prop-typesがまだ入っていなければ、npmインストールしておく必要がある。

MapとSet

v16から、Reactを動かすためにはMapSet、そしてrequestAnimationFrameが必要になった。
JavaScript Environment Requirements - React

これらに対応していないブラウザでもv16以上のReactを動かそうと思ったら、対応が必要になる。

例えば、Androidの標準ブラウザは、MapSetに対応していない。

職場の実機で試したところ大丈夫だったのだが、エミュレータでは予想通りのエラーが出た。

Uncaught ReferenceError: Set is not defined 

自分が担当しているウェブアプリはAndroidの標準ブラウザもサポートしないといけないため、Polyfillを入れることにした。

core-jsをnpmインストールして、エントリポイントであるJSファイルに以下のように記述すれば、解決する。

import 'core-js/es6/map';
import 'core-js/es6/set';

Polyfillをどのように使うのかはプロジェクト毎にやり方があるだろうから、それに沿う感じで。

ちなみに、エミュレータでの動作確認では、この記事が役に立った。
chrome://inspect/でDevToolsを開けるのはすごく便利だ。
フロントエンドエンジニアがAndroid標準ブラウザをデバッグする – T – Medium

Enzyme

テストツールとしてEnzymeを使っている場合、Reactのv16へのバージョンアップに合わせて、Enzymeのバージョンを3以上に上げる必要がある。

v3からは、アダプターの導入と設定が必要になる。

enzyme/migration-from-2-to-3

$ npm i -D enzyme-adapter-react-16

enzyme-adapter-react-16を使うには、依存関係にあるreactreact-domreact-test-rendererが必要。

そして、configure()を行う必要がある。

import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

Enzyme.configure({ adapter: new Adapter() });

テストの設定ファイルなどに書いておくのが妥当だろう。

なお、v3からはshallowの挙動が変わるので注意が必要。

参考資料