前回の続き。数日悩んでいたエラーが解決できたのでメモ。
[遭遇したエラー]
エラーの前に、環境情報を。
$ react-native --version react-native-cli: 2.0.1 react-native: 0.57.5
package.jsonはこんな感じ。
react-native init時からの変更点としては、react-native-svgを追加したのと、jestのtransformIgnorePatternsを追加したくらい。
{
"name": "pixelarn",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.6.1",
"react-native": "^0.57.5",
"react-native-svg": "^8.0.8"
},
"devDependencies": {
"babel-jest": "23.6.0",
"jest": "23.6.0",
"metro-react-native-babel-preset": "0.49.1",
"react-test-renderer": "16.6.1"
},
"jest": {
"preset": "react-native",
"transformIgnorePatterns": [
"node_modules/(?!(react-native|react-native-svg)/)"
]
}
}
プロジェクトの再作成前は起動しなくて途方にくれていたアプリも、シミュレータで正しく起動できる。
ここに、テストコードを追加していく。
内容は、シンプルなスナップショットテストのみ。PixelaのAPIにデータを取りに行く際に利用しているfetchメソッドのモックがあるだけで、React Nativeプロジェクトの再作成前に動いていたことは確認済み。
import 'react-native';
import React from 'react';
import App from '../App';
import renderer from 'react-test-renderer';
it('renders correctly', () => {
const tree = renderer.create(
<App/>
);
expect(tree.toJSON()).toMatchSnapshot()
});
global.fetch = () => ({
then: () => {}
})
しかし、npm testでテストを実行すると、次のエラーが発生してしまう。
$ npm test
> pixelarn@0.0.1 test /Users/akito/Develop/pixelarn
> jest
FAIL __tests__/App.js
● Test suite failed to run
Cannot find module 'AccessibilityInfo' (While processing preset: "/Users/akito/Develop/pixelar
n/node_modules/react-native/Libraries/react-native/react-native-implementation.js")
at Object.get AccessibilityInfo [as AccessibilityInfo] (node_modules/react-native/Libraries/
react-native/react-native-implementation.js:22:12)
at node_modules/lodash/_baseClone.js:163:23
at arrayEach (node_modules/lodash/_arrayEach.js:15:9)
at baseClone (node_modules/lodash/_baseClone.js:160:3)
at cloneDeepWith (node_modules/lodash/cloneDeepWith.js:37:10)
at OptionManager.mergeOptions (node_modules/babel-core/lib/transformation/file/options/option-manager.js:206:44)
「Cannot find module 'AccessibilityInfo' (While processing preset」でググると、そこそこの件数がヒットする。
react-nativeモジュールのバージョンを下げればうまくいく、と言う報告もあるが、一年前のv0.44.0とかの話で、流石にそこまで下げると他のモジュールが動かなくなりそうなので、この方針は却下。
Babel周りのライブラリのバージョンがずれてるから直せ、ということらしい。しかし、初期化処理でインストールしたものがずれてるってことなのか?と思いつつよくよくpackage.jsonを見直してみると、自分のpackage.jsonにはbabel-preset-react-nativeモジュールがないことに気がつく。
確かに、以前Web+DB Pressの天気予報アプリを写経した際にも、同じモジュールを使っている。今回初期化したpackage.jsonには似たような名前のmetro-react-native-babel-presetと言うモジュールが含まれているが、これでは駄目なのだろうか……。
[試しにbabel-preset-react-nativeをインストールしてみる]
まあ試すだけなら無料だし、ということで、藁にもすがる思いでコマンドを実行する。
$ npm install babel-preset-react-native --save-dev + babel-preset-react-native@4.0.1 added 44 packages from 3 contributors and audited 35619 packages in 12.16s found 0 vulnerabilities
特に問題なくインストール完了。
アプリの方は問題なく起動する。問題はテストコードだ。ドキドキ。
$ npm test > pixelarn@0.0.1 test /Users/akito/Develop/pixelarn > jest PASS __tests__/src/Date.js PASS __tests__/App.js (8.278s) › 1 snapshot written. Snapshot Summary › 1 snapshot written from 1 test suite. Test Suites: 2 passed, 2 total Tests: 5 passed, 5 total Snapshots: 1 written, 1 total Time: 9.93s Ran all test suites.
無事テストが通った!グリーンのpassedの文字が目に優しい。

[原因と思しきもの]
と、ここで、「.babelrc」を変更していたことに思い当たる。
プロジェクト初期化時の.babelrcの記述は以下の通り。
{
"presets": ["module:metro-react-native-babel-preset"]
}
これを、天気予報アプリの構成に合わせて、次のように変更していた。
{
"presets": ["react-native"]
}
変更した理由は、module:metro〜がエラーだとかいうメッセージを見たからだった気もするが、そのエラーを見たのはそもそも移行前のプロジェクトでmetro-react-native-babel-presetをアンインストールしたからだった気もするし、定かではない。
とりあえず解決できたので、またハマらないようにメモしておく。
[まとめ]
・Cannot find module `XXX` (While processing preset ... のエラーはbabel-preset-react-nativeをインストールすると解消する、かもしれない
今日のブログ執筆BGMはこちら。