如何在create-next-app(TypeScript)中导入m4v视频?遇模块未找到错误
解决Next.js导入本地m4v视频模块找不到的问题(无需放入public文件夹)
问题重现
运行项目时出现以下模块找不到错误:
./components/Hero.tsx:2:0 Module not found: Can't resolve '../media/HeroVideo1-Red-Compressed.m4v' 1 | import React, { useState } from 'react'; > 2 | import Video from '../media/HeroVideo1-Red-Compressed.m4v'; 3 | import { Button } from './SharedStyles'; 4 | import styled from 'styled-components' 5 | import { MdKeyboardArrowRight, MdArrowForward } from 'react-icons/md'; Import trace for requested module: ./pages/index.tsx
已尝试在./media目录添加index.d.ts声明declare module '*.m4v',消除了编辑器波浪线报错,但客户端运行时仍报错,且不想将视频放入public文件夹。
解决方案
核心原因是Next.js默认的webpack配置未处理.m4v格式文件,需添加对应的loader并调整配置:
- 安装file-loader依赖
file-loader用于将视频文件打包到静态资源目录,返回资源路径:
npm install file-loader --save-dev # 或使用yarn yarn add file-loader -D
- 配置Next.js的webpack规则
在项目根目录创建或修改next.config.js,添加处理.m4v文件的规则:
module.exports = { webpack: (config, { isServer }) => { // 新增m4v文件处理规则 config.module.rules.push({ test: /\.m4v$/, use: { loader: 'file-loader', options: { publicPath: '/_next/static/media/', outputPath: 'static/media/', name: '[name].[hash].[ext]', // 打包后文件名带哈希,利于缓存 esModule: false, }, }, }); return config; }, };
- 确保类型声明被TS识别
检查tsconfig.json的include字段,确保包含所有.d.ts文件:
{ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.d.ts"], "exclude": ["node_modules"] }
同时确认./media/index.d.ts的声明正确:
declare module '*.m4v' { const src: string; export default src; }
- 重启开发服务器
修改配置后需要重启Next.js开发服务器,让新的webpack配置生效。
原理说明
添加file-loader后,webpack会将.m4v文件复制到Next.js的静态资源目录(/.next/static/media/),并在导入时返回该文件的访问路径,这样运行时就能正确加载视频,且无需将文件放入public文件夹。
内容的提问来源于stack exchange,提问作者Tara
相关产品推荐
相关产品推荐

