reactjs - CRA/TypeScriptでmp3ファイルをインポートする
私は CRA v3.2.0 で作られたシンプルなアプリを持っています。TypeScript をデフォルト設定で使用しています(下記の tsconfig.ts を参照)。/src/sounds/ に「click_hi.mp3」という mp3 ファイルがあり、コンポーネントで使用したいのですが、mp3 をインポートすると Cannot find module 'sounds/click_hi.mp3'.ts(2307) というエラーが出てしまいます。
パスの入力ミスを避けるために、ファイルをコンポーネントと同じフォルダに置いてみました。しかし、うまくいきませんでした… mp3ファイルをどうやってインポートできますか?
App.tsx
import React, { useState, useRef, useEffect } from "react";
import ReactDOM from "react-dom";
import { Sampler } from "tone";
import ClickHi from 'sounds/click_hi.mp3'
export default function ExercisePage() {
const [isLoaded, setLoaded] = useState(false);
const sampler = useRef(null);
useEffect(() => {
sampler.current = new Sampler(
{ "A1": ClickHi },
{
onload: () => {
setLoaded(true);
}
}
).toMaster();
}, []);
const handleClick = () => sampler.current.triggerAttack("A1");
return (
<div>
<button disabled={!isLoaded} onClick={handleClick}>
start
</button>
</div>
);
}
tsconfig.ts
{
"compilerOptions": {
"baseUrl": "src",
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
},
"include": ["src"]
}
回答 #1
まだこの問題を抱えていて、私と同じようにアセットを public フォルダに置きたくない場合は、次のようにして「default」を使用してください:
const path = require('../assets/audio/some_audio.mp3');
setAudio(new Audio(path.default));
注: この問題は TypeScript を使用している場合にのみ発生しました。mp3 のモジュールを宣言する必要があります。プロジェクトの src フォルダに "audio.d.ts" のような名前のファイルを追加し、内容を declare module '.*mp3'; のようにしてください。
これを使ったシンプルなアプリの動作例: https://geocarlos.github.io/leiamos/
回答 #2
オーディオファイルをpublicフォルダーに置き、次のように参照することで修正しました:
useEffect(() => {
sampler.current = new Sampler(
{ A1: `${process.env.PUBLIC_URL}/audio/click_hi.mp3`},
() => {
setLoaded(true);
}
).toMaster();
}, []);
