Reactでmp3を読み込めなかった時の対処法✨
こんにちは、Ryotaです。
今回は業務内でぶち当たった壁、React/TypeScriptのコンポーネントでMP3をimportする方法についてです。
「いや、インポートしたらええやん」って感じなのですが、それだけだと実は全く相手にして貰えないので(笑)そこを乗り越える為に必要だった事を備忘録として記します。
同じ目に遭ってる方の参考になれば幸いです。
今回の目的
現在業務の中でモバイルアプリ開発を行っておりReact Nativeを使用しています。
そんな中でAPIを叩き、ステータス200が返ってくれば成功、キラリーン〜という効果音を出すというのが今回の目的です。
立ちはだかる壁
これを実現する為にはまずライブラリ「React-native-sound」をインストールする必要があります。今回のプロジェクトではyarnを使っていたのでまずはこちら。
yarn add react-native-sound
これでプロジェクトのルートディレクトリにあるpackage.jsonに以下のように追加されます。
"dependencies": {
...
"react-native-sound": "^0.11.2",
}
よっしゃ!これで「React-native-sound」が使えるぜ!
ということで以下のような感じで書きました。
import { FC, useState } from 'react';
import Sound from 'react-native-sound';
import SoundFile from '@/assets/QrSuccessSound.mp3';
import { useMutation } from 'react-query';
export const MyComponent: FC = () => {
const successSound = new Sound(SoundFile, '', (error) => {
if (error !== null) {
console.log('Failed to load the sound', error);
return;
}
});
// ここでAPIを叩く。今回はuseMutationを使用した例です
{
onSuccess: async () => {
successSound.play();
},
onError: (error) => {
console.log('エラーですよ')
}
}
);
return (
// コンポーネントのJSX
);
};
そして意気揚々と実行してみると...
Cannot find module '/assets/QrSuccessSound.mp3'.
え?
API叩くの成功してるのに音が出ない?
え〜〜〜〜〜〜〜音ならんやん!!もうあかんや〜〜〜〜〜ん!!
となるのです。
原因と対処法
調べてみると、TypeScriptはデフォルトではファイルの拡張子が.ts、.tsx、.d.tsのファイルをモジュールとして扱い、MP3ファイルのような非標準の拡張子は認識しないことが原因で、インポートできなかったようです。
なので行ったのは、
カスタム型定義ファイルの作成
まず.mp3
ファイルを扱うためのカスタム型定義ファイル audio.d.ts を作成します。
このファイルは、プロジェクトのルートディレクトリに任意の名前のフォルダを作成して、その中に保存します。内容はこんな感じで書けばOK!
declare module '*.mp3';
これで、TypeScript はプロジェクト内の任意の場所から .mp3 ファイルをインポートして使用することができます。
と言うことで再び実行してみると
LOG successSound.play: {
無事に成功してちゃんと音が出ました✨やったー🙌
ちゃんと音が出た時はめちゃくちゃ嬉しかったです😆
まとめ
- TypeScriptは標準のファイル拡張子(.ts、.tsx、.d.ts)以外のファイルをモジュールとして認識しないため、カスタム型定義ファイルが必要
- カスタム型定義ファイルを作成する際は、拡張子が.mp3のファイルをモジュールとして宣言する
皆さんもピコンピコン音を出したい時はぜひ参考にしてみてください😊
ちなみに動画ファイルに関しても同じような感じでreact-native-video-player
というライブラリがあります。こちらを使う場合もファイルが標準拡張子でない場合は同じように試してみるといけるはずです✨(試してはないので頑張ってください!)
以上、最後までお読みいただき、ありがとうございました✨
Discussion