How to fix 'module not found' for audio files using file-loader? Images, CSS, and JSON are working just fine

Viewed 6641

I'm new to building a browser game using Typescript/React/Redux/etc. and am trying to implement audio for the game. I've been attempting to import audio files in the same way I import image and json files, but so far to no avail. After adding mp3 to my webpack config using 'file-loader', I try importing a sample mp3 file I put in the same location as an image file I've been able to successfully import, but when I try to run web pack, it tells me that the mp3 module cannot be found.

sample file

import React from "react";
import spriteSheet from "../assets/spritesheet.gif";
import audioFile from "../assets/pillRotate.mp3";

import { Gameboard } from "./Gameboard";

export class MainGameComponent extends React.Component {
    render() {
        return (
            <div>
                <img id="spriteSheet" src={spriteSheet} hidden={true} />
                <audio src={audioFile}></audio>
                <Gameboard />
            </div>
        )
    }
}

export default MainGameComponent;

webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
    entry: "./src/index.tsx",
    output: {
        filename: "bundle.js",
        path: __dirname + "/dist"
    },

    resolve: {
        extensions: [".ts", ".tsx", ".js"]
    },

    module: {
        rules: [
            { 
                test: /\.tsx?$/, 
                use: "awesome-typescript-loader" 
            },
            {
                test: /\.(png|jpg|gif|mp3)$/,
                use: 'file-loader',
            },
            {
                test: /\.css$/i,
                use: ['style-loader', 'css-loader'],
            },
        ]
    },

    plugins: [
        new HtmlWebpackPlugin({
            hash: true,
            title: 'Dr. Mario',
            template: 'index.html',
            filename: './index.html'
        })
    ]
};

ERROR in [at-loader] ./src/components/MainGame.tsx:3:23 TS2307: Cannot find module '../assets/pillRotate.mp3'.

3 Answers

If you use create-react-app to setup your React project. You can try to add the follow lines in your react-app-env.d.ts:

declare module '*.mp3' {
  const src: string;
  export default src;
}

When you try to import a mp3 file in *.tsx, typescript compiler will try to find out its declaration, the same way as you import another class file. But when you try to require a mp3 file, like this:

<audio src={require('./assets/xxx.mp3')}>

ts will not try to find its declaration, but handle it to webpack loader. This why in this way there is no compile error.

Using require() worked for me

<img id="spriteSheet" src={require("../assets/spritesheet.gif")} hidden={true} />

When importing the audio file using Typescript, make sure you don't have brackets around the filename.

import audioFile from "./audio_test_sound.mp3"
Related