こんにちは。今週は、1週間会社の夏休み休暇中なのですが、引き続きReact Nativeと格闘しております。今日は、Azure Storgeとの連携に際して発生した問題のトラブルシューティング。
いやあ・・かなり時間を食いました・・・
Contents
前提
以下のパッケージ・ランタイムバージョンで発生した問題になります。
- React Native (0.63.x)
- Expo (42.0.3)
- TypeScript (4.4.3)
- @azure/storage-blob (12.8.0)
問題
Azure Storageに格納したBlobのSAS URLを取得するために、以下のコードを実行しようとすると、エラーが発生した。
以下にも記述するが、crypto以外にも、http, tls, net, http, https, timers・・・等個別に対応しても永遠と出てくる・・・。
import { BlobServiceClient} from '@azure/storage-blob';
const AZURE_STORAGE_CONNECTION_STRING = "";
// Create Blob Client
const blobServiceClient = BlobServiceClient.fromConnectionString(AZURE_STORAGE_CONNECTION_STRING);
undefined Unable to resolve module crypto from プロジェクトディレクトリ/node_modules/@azure/storage-blob/dist/index.js: crypto could not be found within the project.
If you are sure the module exists, try these steps:
1. Clear watchman watches: watchman watch-del-all
2. Delete node_modules and run yarn install
3. Reset Metro's cache: yarn start --reset-cache
4. Remove the cache: rm -rf /tmp/metro-*
試行錯誤
まずは、cryptoエラーに対処する方法を色々と探してみる。
cryptoを追加してみる
とりあえず、最初にエラー内容をストレートに解釈して、cryptoを追加してみた。
yarn add crypto
追加はできた、が、結果、なんかエラーが増えた笑
Failed building JavaScript bundle.
While trying to resolve module `crypto from file
'xxx/node_modules/@azure/storage-blob/dist/index.js`, the package `xxx/node_modules/crypto/package.json` was successfully found. However, this package itself specifies a `main` module field that could not be resolved (`xxx/node_modules/crypto/index.js`. Indeed, none of these files exist:
* /xxx/node_modules/crypto/index.js(.native|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx|.android.js|.native.js|.js|.android.jsx|.native.jsx|.jsx|.android.json|.native.json|.json)
* /xxx/node_modules/crypto/index.js/index(.native|.android.ts|.native.ts|.ts|.android.tsx|.native.tsx|.tsx|.android.js|.native.js|.js|.android.jsx|.native.jsx|.jsx|.android.json|.native.json|.json)
どうやら、crypto自体はnode.js向けのモジュールっぽいので、React Nativeでは直接利用することができなさそうだった。なので、react-native-cryptoとかReact Native向けのパッケージが出ているっぽい。
別の方法をさがす。
@azure/storage-blobのバージョンを下げる -> ダメだった
azure/storage-blob固有の問題かなぁと思って、Azure SDKのGithub Issueを漁ってみると、同じエラーに当たっている人のIssueを発見した。
ここのDiscussionによると、暫定的ではあるがstorage-blobのバージョンを下げることでうまく動いたようなので試してみる。
https://github.com/Azure/azure-sdk-for-js/issues/13267
結果、何も変わらずだった。
expo-cryptoをcryptoとしてインストール -> いけた
最終的にこの方法でこのエラー自体は解消できた。
以下のIssueを見て、パッケージのRenameができることを知る。
https://stackoverflow.com/questions/64708318/react-native-crypto-module-issue
そして、expoを利用している場合は、expoが提供するexpo-cryptoを利用するっぽい、というのもなんとなくわかった。
ので、このexpo-cryptoをcryptoとしてインストールすれば、動くのでは?と思って試してみた。
yarn add crypto@yarn:expo-crytpo
結果、動いた。(cryptoのエラーは出なくなった!)
永遠と続く Module Not Found Error
とここで次の問題が・・・今度は”http”というモジュールがないとのこと・・・
Unable to resolve module http from /xxx/node_modules/@azure/core-http/dist/index.js: http could not be found within the project.
同じような方法で、各モジュール、React Native版を取得してみたら、いくつかは動いたが、今度はまた別のモジュールのエラーが出てくるといういたちごっこ。結局、以下をひたすら続けて、最後timersモジュールがない、と言われたところで同様の方法が通じず行き止まり。
yarn add http@yarn:react-native-http
yarn add https@yarn:react-native-https
yarn add tls@yarn:react-native-tls
yarn add net@yarn:react-native-net
というか、こんな個別にモジュールを足していく方法はなんかおかしい。そもそもReact Native + Expo (+TypeScript?)で本当に@azure/storage-blobって使えるの?というところから怪しい・・・
ということで、もはや自分では解決できなくなったので、Github Issueを起票してみた。
https://github.com/Azure/azure-sdk-for-js/issues/17694
こちらの反応を待ちたいと思う・・・
なんかReact NativeでAzure Storageを使うには闇が深そうだ・・・
この問題、日本語記事がほとんどなかったように思うので、今後同じ問題につまづかれた方の役に立つことを願います・・・
続く
[番外編] ReactNativeをもっと学ぶなら・・・
React Nativeをもっとちゃんと学びたい!という方は、こちらにおすすめコンテンツをまとめましたので、ご参考にしていただければと思います・・!
土台のJavaScript/TypeScriptに不安がある方は、こちらもまとめましたので、ご参考になりましたら幸いです。
情報ご共有ありがとうございます。
2022年11月現在、同じくNode.jsの標準ライブラリーcryptoを使うパッケージ(web3-eth-accounts)を執筆者様と同じ環境で利用しようとしているのですが、同じ問題ではまっております。。。
Expoを使う場合、ネイティブライブラリーを利用する際のハードルが極端に高くなるイメージです。。。(簡易なアプリケーションならそれでもいいんでしょうか。。。)
アプリ開発入門としては適していますが、この状況が改善されないとReact Native Expo の未来は暗いかもしれません