vite+vue3项目打包后,nginx部署到linux服务器,访问时一直报错:
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.
报错翻译
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类型检查。
报错截图:
尾号24c.js文件报错,我们进一步,去网络面板去排查
Network资源请求截图
找到这个报错的文件,看看返回的是什么?
很明显,这个请求的是一个js资源
报错分析
我们知道,当项目代码打包成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作为前缀,导致打包的时候,也带上去了,如下代码:
export default defineConfig(({ mode }) => { return { base: '/app', build: { ... }, server: { ... }, plugins: [ ... ], } })
总结
当我们发现报错了,就一点点排查即可
发现js请求返回了一个html
联想到nginx代理的规则
说明找不到这个资源文件
就看一下,到底有没有这个资源文件
最终找到原因所在,base多了一个前缀