Express搭建Three.js项目出现非JavaScript MIME类型模块加载错误
解决方案
问题本质
你在type="module"的JS文件中直接导入.glsl、.jpg这类非JS后缀的文件,浏览器会默认将这些文件识别为JS模块,要求服务器返回application/javascript类型的MIME,但你的Express静态服务返回的是文件本身的对应MIME类型,不符合模块加载的MIME校验规则,所以触发报错。另外你现有的server.js还有语法错误,app.use(express.static('public')缺少闭合括号,需要先补上。
方案1:无打包工具,直接修改现有代码(最快修复)
直接放弃非JS文件的ES模块导入写法,用原生API加载对应资源:
- 删除
main.js顶部的3行非JS导入语句:
// 移除以下三行代码 import vertexShader from "./glsl/vertex.glsl"; import fragmentShader from "./glsl/fragment.glsl"; import img from "./mannequin.jpg";
- 改造
createMesh方法,异步加载GLSL文件,图片直接传路径给纹理加载器:
async createMesh() { // 异步加载GLSL着色器代码 const vertexShader = await fetch('./glsl/vertex.glsl').then(res => res.text()) const fragmentShader = await fetch('./glsl/fragment.glsl').then(res => res.text()) this.geometry = new THREE.PlaneGeometry(0.4, 0.6, 32, 32); this.material = new THREE.ShaderMaterial({ vertexShader, fragmentShader, uniforms: { uTime: { value: 0.0 }, // 直接传入图片路径即可,不需要提前导入 uTexture: { value: new THREE.TextureLoader().load('./mannequin.jpg') } }, side: THREE.DoubleSide }); this.mesh = new THREE.Mesh(this.geometry, this.material); this.scene.add(this.mesh); }
- 改造
init方法,异步调用createMesh:
async init() { await this.createMesh(); this.addEvents(); }
方案2:使用打包工具适配(适合长期开发)
如果后续项目复杂度会提升,可以用Vite作为开发打包工具,原生支持静态资源导入,额外配置插件即可支持GLSL文件导入:
- 项目根目录执行命令初始化Vite项目:
npm create vite@latest . -- --template vanilla
- 安装依赖:
# 安装Three.js npm i three # 安装GLSL导入支持插件 npm i vite-plugin-glsl -D
- 根目录新建
vite.config.js配置文件:
import glsl from 'vite-plugin-glsl' export default { plugins: [glsl()] }
- 将原有
public目录下的资源按照Vite的规范存放:静态资源放在public目录,业务JS代码放在src目录,原有非JS资源的import写法可以正常使用,执行npm run dev启动开发服务即可。
内容的提问来源于stack exchange,提问作者Abdulsalam Almahdi
相关产品推荐
相关产品推荐

