Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.
上述报错完整信息
- 项目是vue3的项目
- 脚手架是vite
- 服务器用nginx做代理转发
报错翻译
Failed to load module script: Expected a JavaScript module script but the server responded with a MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.
翻译:
加载模块脚本失败:需要一个JavaScript模块脚本,但服务器的MIME类型为“text/html”。根据HTML规范,对模块脚本强制执行严格的MIME类型检查。
报错截图
添加图片注释,不超过 140 字(可选)
尾号24c.js文件报错,我们进一步,去网络面板去排查
Network资源请求截图
添加图片注释,不超过 140 字(可选)
- 找到这个报错的文件,看看返回的是什么?
- 很明显,这个请求的是一个js资源
添加图片注释,不超过 140 字(可选)
报错分析
- 我们知道,当项目代码打包成dist包后,部署到服务器上
- 当我们访问这个服务器上的项目的时候,本地浏览器会访问对应资源(即请求资源)
- 如果请求找不到某个资源,nginx的location代码会返回index.html给到请求,以尽可能保证请求不会404
- 即下方代码
<!---->
location / {
root C:/nginx-1.18.0/html/project/dist;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
上述释义:
- root 是项目的根目录,即为打包的dist所在的位置路径
- index是项目的入口文件的名称,一般都是 index.html index.htm(古老的php项目,还可以再添加一个index.php)
即:index index.html index.htm index.php; 也是可以的
- try\_files 当请求来时,nginx会按照try\_files后面的顺序依次遍历查找是否有对应的文件,其中$uri 指的是你addres地址栏携带的后缀,比如访问的是 localhost:8080/admin,那么这里的$uri就是 /admin
- 上述代码的try\_files,会依次访问/admin,/admin/
- 当都找不到的时候,会把index.html页面给到用户
- 即为:兜底的作用
- 换句话说,就是没有这个app/24c.js文件
- 导致请求不到,所以返回一个index.html文件给请求
- 这个app看了一下,dist中,还真的是没有这个文件夹目录
- 那,代码中怎么会有呢?
- 最后发现,原来是vite.config.js文件中的base,多了一个/app作为前缀,导致打包的时候,也带上去了,如下代码:
- 最后发现,原来是vite.config.js文件中的base,多了一个/app作为前缀,导致打包的时候,也带上去了,如下代码:
- 最后发现,原来是vite.config.js文件中的base,多了一个/app作为前缀,导致打包的时候,也带上去了,如下代码:
<!---->
export default defineConfig(({ mode }) => {
return {
base: '/app',
build: { ... },
server: { ... },
plugins: [ ... ],
}
}
)
总结
- 当我们发现报错了,就一点点排查即可
- 发现js请求返回了一个html
- 联想到nginx代理的规则
- 说明找不到这个资源文件
- 就看一下,到底有没有这个资源文件
- 最终找到原因所在,base多了一个前缀
base前缀,可以用在同一个域名ip服务器下,部署多个项目,这个知识点,我们下回再议...
A good memory is better than a bad pen. Record it down...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。