不思議な挙動をするのでメモ。
import { Image } from 'react-native'
// OK
function MyComponent() {
return <Image source={require('./assets/image.png')} />
}
// OK
function MyComponent() {
return <Image source={require('@some/package/assets/image.png')} />
}
// NG
function MyComponent() {
const imageName = '@some/package/assets/image.png'
return <Image source={require(imageName)} />
}
// OK
function MyComponent() {
const imageSource = require('@some/package/assets/image.png')
return <Image source={imageSource} />
}
変数に対して require
はできない。 こんな感じのエラーになる。
error: bundling failed: Error: Unable to resolve module `@some/package/assets/image.png` from `/Users/kazuya/MyComopnent.tsx`: The
module `@some/package/assets/image.png` could not be found from `/Users/kazuya/`. Indeed, none of these files exis
t:
* `image.png`
* `/@some/package/assets/image.png/index(.native||.android.js|.native.js|.js|.android.json|.native.json|.json|.android.ts|.native.t
s|.ts|.android.tsx|.native.tsx|.tsx)`
そして驚くべきは、これ。
import { Image } from 'react-native'
// OK
function MyComponent() {
return <Image source={require('@some/package/assets/image.png')} />
}
// NG...!?
function MyComponent() {
return <Image source={require(`@some/package/assets/image.png`)} />
}
違いとしては、
'
が
`
になっただけだなのだが、これもエラーになった。
しょうもないケースだが、ちょっとはまった。
追記
最近感覚的にわかってきたが、 Facebook 系のツール(React Native CLI, Jest等)は、起動時に全てのモジュールを巻き上げて、 Jest-Haste-Map という場所に格納するようだ。おかげで Webpack より Metro の方が体感速いのだと思われる。(ソースは無い)
起動時に巻き上げるため、動的な require
はできない。 `
内は (babelなどを介さなければ) 実行時に評価される文字列なので、起動時に巻き上げるのに失敗する。