You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Webpack开发服务器加载MP3文件报404错误求助

MP3文件加载404错误求助(Webpack开发服务器环境)

开发音频播放器时,启动Webpack开发服务器后出现MP3文件加载404(Not Found)错误,尝试配置devServer的publicPath后问题仍未解决,求有相关经验的开发者帮忙排查。

相关代码及配置

Webpack配置

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const PostCssPresetEnv = require('postcss-preset-env');

const mode = process.env.NODE_ENV || 'development';
const devMode = mode === 'development';
const target = devMode ? 'web' : 'browserslist';
const devtool = devMode ? 'source-map' : undefined;

module.exports = {
    mode,
    target,
    devtool,
    devServer: {
        port: 3000,
        open: true,
        hot: true, 
    },
    entry: ['@babel/polyfill', path.resolve(__dirname, 'src/app/js', 'index.js')],
    output: {
        path: path.resolve(__dirname, 'src/app/dist'),
        clean: true,
        filename: "index.[contenthash].js",
        assetModuleFilename: "assets/[name][ext]",
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: path.resolve(__dirname, 'src/app', 'index.html'),
        }),
        new MiniCssExtractPlugin({
            filename: "index.[contenthash].css",
        }),
    ],
    module: {
        rules: [
            {
                test: /\.html$/i,
                loader: 'html-loader',
            },
            {
                test: /\.s?css$/i,
                use: [
                    devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
                    'css-loader',
                    {
                        loader: 'postcss-loader',
                        options: {
                            postcssOptions: {
                                plugins: [PostCssPresetEnv],
                            },
                        },
                    },
                    'sass-loader',
                ],
            },
            {
                test: /\.(ttf|otf|woff|woff2)$/i,
                type: 'asset/resource',
                generator: {
                    filename: "fonts/[name][ext]"
                }
            },
            {
                test: /\.mp3$/,
                loader: 'file-loader',
            },
            {
                test: /\.(jpeg|jpg|png|gif|webp|svg)$/i,
                use: [
                    {
                      loader: 'image-webpack-loader',
                      options: {
                        mozjpeg: {
                          progressive: true,
                        },
                        optipng: {
                          enabled: false,
                        },
                        pngquant: {
                          quality: [0.65, 0.90],
                          speed: 4
                        },
                        gifsicle: {
                          interlaced: false,
                        },
                        webp: {
                          quality: 75
                        }
                      }
                    },
                  ],
                type: 'asset/resource',
            },
            {
               test: /\.m?js$/i,
               exclude: /(node_modules|bower_components)/,
               use: {
                loader: 'babel-loader',
                options: {
                    presets: ['@babel/preset-env'],
                },
               },
            },
        ],
    },
}

核心JS代码

import '../index.html';
import '../scss/style.scss';
import {data} from './data.js';

const AudioController = {
    state: {
        audios: [],
    },

    init() {
        this.initVariables();
        this.renderAudios();
    },

    initVariables() {
        this.audioList = document.querySelector('.items');
    },

    renderAudios() {
        data.forEach((item) => {
            const audio = new Audio(`../../assets/audio/${item.link}`);
            
            audio.addEventListener('loadeddata', () => {
                const newItem = { ...item, duration: audio.duration, audio };
                this.state.audios = [ ...this.state.audios, newItem ];
            })
        })
    }
}

AudioController.init();

数据对象(data.js)

export const data = [
    {
      id: 1,
      link: "Hurt_You.mp3",
      genre: "R&B",
      track: "Hurt You",
      group: "The Weeknd",
      year: 2020,
    },
    {
      id: 2,
      link: "In_Your_Eyes.mp3",
      genre: "R&B",
      track: "In Your Eyes",
      group: "The Weeknd",
      year: 2020,
    },
    {
      id: 3,
      link: "The_Hills.mp3",
      genre: "R&B",
      track: "The Hills",
      group: "The Weeknd",
      year: 2020,
    },
    {
      id: 4,
      link: "Too_Late.mp3",
      genre: "R&B",
      track: "Too Late",
      group: "The Weeknd",
      year: 2020,
    },
];

报错情况

请求../../assets/audio/Hurt_You.mp3等音频文件时返回404 Not Found。


解决方案

1. 替换file-loader为Webpack5内置的asset/resource模块

Webpack5已弃用file-loader这类单独的资源加载器,改用内置的asset模块处理静态资源。修改Webpack配置中的MP3规则:

{
    test: /\.mp3$/,
    type: 'asset/resource',
    generator: {
        filename: "assets/audio/[name][ext]" // 指定音频文件输出到dist/assets/audio目录
    }
}

2. 通过import正确引入音频资源

Webpack开发服务器会将处理后的资源放在内存中,手动拼接相对路径无法访问这些资源。需要通过import让Webpack追踪资源:
修改data.js:

// 导入音频文件,路径根据你的项目结构调整
import hurtYou from '../../assets/audio/Hurt_You.mp3';
import inYourEyes from '../../assets/audio/In_Your_Eyes.mp3';
import theHills from '../../assets/audio/The_Hills.mp3';
import tooLate from '../../assets/audio/Too_Late.mp3';

export const data = [
    {
      id: 1,
      link: hurtYou, // 使用导入的资源路径变量
      genre: "R&B",
      track: "Hurt You",
      group: "The Weeknd",
      year: 2020,
    },
    {
      id: 2,
      link: inYourEyes,
      genre: "R&B",
      track: "In Your Eyes",
      group: "The Weeknd",
      year: 2020,
    },
    {
      id: 3,
      link: theHills,
      genre: "R&B",
      track: "The Hills",
      group: "The Weeknd",
      year: 2020,
    },
    {
      id: 4,
      link: tooLate,
      genre: "R&B",
      track: "Too Late",
      group: "The Weeknd",
      year: 2020,
    },
];

然后修改JS中的音频实例化代码,直接使用item.link:

const audio = new Audio(item.link);

3. 验证文件目录结构

确保你的MP3文件实际存放在src/app/assets/audio/目录下,与导入路径和Webpack配置的输出路径匹配。


内容的提问来源于stack exchange,提问作者KiKo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 07:19:58