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

Vue+Vite+Express生产环境路由异常:模块脚本MIME类型错误

问题:Vue+Vite+Express生产环境嵌套路由资源加载失败

问题现象

生产环境测试时,非嵌套URL(如/home、/access)可正常访问,但嵌套URL(如/access/error、/access/login)触发以下错误:

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.

相关代码

index.html.ejs

<!DOCTYPE html>
<html>
  <head>
      <% if (environment === 'production') { %>
      <link rel="stylesheet" href="<%= manifest['src/main.css'].file %>" />
      <% } %>
  </head>
  <body>
    <div id="app"></div>
    <% if (environment == "production") { %>
    <script type="module" src="<%= manifest['src/main.js'].file %>"></script>
    <% } else { %>
    <!-- this link may be @vite instead of @vite/client-->
    <script type="module" src="http://localhost:5173/@vite/client"></script>
    <script type="module" src="http://localhost:5173/src/main.js"></script>
    <% } %>
  </body>
</html>

Express服务器代码

import homepageRouter from "./homepage_router.js";
import apiRoutes from "./api_router.js";

const app = express();

app.set('view engine', 'ejs');

const distPath = path.join(path.resolve(), "dist");
app.use("/", express.static(distPath));

app.use('/', apiRoutes);
app.use('/', homepageRouter);

// set port, listen for requests
app.listen(process.env.PORT, () =>{
    console.log(`Server is running on port ${process.env.PORT}`);
})    

homepageRouter代码

router.get("/*", async (_req, res) => {
  const data = {
    environment: 'production',
    manifest: await parseManifest('production'),
  };

  res.render("index.html.ejs", data);
});

const parseManifest = async (enviroment) => {
  if (enviroment != 'production') return {};

  const manifestPath = path.join(path.resolve(), "dist", "manifest.json");
  const manifestFile = await fs.readFile(manifestPath);

  return JSON.parse(manifestFile);
};

原因分析

问题核心是资源路径使用了相对路径。比如在/access/error页面中,浏览器会把src/main.xxx.js这类相对路径解析为/access/error/src/main.xxx.js——这个路径不存在,Express的通配路由(router.get("/*"))会返回index.html,导致资源请求拿到的是HTML文件而非JS/CSS,从而触发MIME类型不匹配错误。

解决方案

1. 改用绝对路径加载资源

修改index.html.ejs中的资源引用,在路径前加上根路径/,确保浏览器从网站根目录查找资源:

<% if (environment === 'production') { %>
<link rel="stylesheet" href="/<%= manifest['src/main.css'].file %>" />
<% } %>

<% if (environment == "production") { %>
<script type="module" src="/<%= manifest['src/main.js'].file %>"></script>
<% } %>

2. 适配子路径部署(可选)

如果应用部署在子路径下(而非根域名),需要在vite.config.js中设置base字段,比如部署在https://example.com/my-app/,则:

// vite.config.js
export default {
  base: '/my-app/'
}

Vite会自动将manifest.json中的资源路径加上base前缀,配合上述绝对路径引用,资源就能正确加载。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:07:40