Vite SSR配置时为什么服务启动后无法加载CSS文件?

设计师子豪 阅读 61

在用Vite+Vue3搭建SSR项目时,按照官方文档配置了服务端入口和客户端入口,但启动后页面样式完全失效。明明在客户端入口文件里正常导入了main.css,服务端返回的HTML里却看不到内联的样式块。

尝试过在服务端入口手动引入import './assets/main.css',但控制台还是报404错误,显示/assets/main.css找不到。构建出来的dist/client目录里确实有编译后的CSS文件,但访问/assets/main.[hash].css路径返回404。

这是我的vite.config.js配置:


import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  plugins: [vue()],
  build: {
    rollupOptions: {
      input: {'app': './index.html'},
      output: {
        entryFileNames: 'assets/[name]-[hash].js',
        chunkFileNames: 'assets/[name]-[hash].js',
        assetFileNames: 'assets/[name]-[hash].[ext]'
      }
    }
  }
})

服务端用的是@edge-runtime/nodejs-remote-filesystem-http,直接通过fs.readFileSync读取dist/client/index.html返回。是不是哪里没配置静态资源路径?

我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
W″羽墨
这个问题主要是静态资源路径没处理好,服务端没正确托管客户端构建后的静态文件。一般这样处理:

先说下原因,Vite SSR 构建后会生成 dist/client 目录,这里面的文件需要被正确托管。你现在直接用 fs.readFileSync 读取 index.html 返回,但像 CSS、JS 这些静态资源并没有被正确 serve 出来,所以访问就 404 了。

解决方法是在服务端加上静态资源托管。如果你用的是 Node.js 原生 http 模块,可以引入 sirv 这个库来处理静态文件。安装完 sirv 后,在服务端代码里加上类似这样的逻辑:

import sirv from 'sirv'
import { createServer } from 'http'

const clientDist = './dist/client'
const serveStatic = sirv(clientDist, { dev: process.env.NODE_ENV === 'development' })

createServer((req, res) => {
if (req.url.startsWith('/assets/')) {
return serveStatic(req, res)
}

// 其他逻辑保持不变
}).listen(3000)


另外 vite.config.js 里的 build.rollupOptions.input 配置有点问题,SSR 项目建议改成:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
plugins: [vue()],
build: {
rollupOptions: {
input: {
main: './index.html',
// 其他入口...
}
}
}
})


记得在开发环境也要注意静态资源路径的问题,可以在 server.js 里加个判断,开发环境下用 vite 的中间件,生产环境用 sirv 托管静态文件。

最后提醒一下,服务端渲染时 CSS 提取要注意顺序,确保样式按预期加载。有时候样式失效可能是因为插件顺序不对,确保 @vitejs/plugin-vue 插件在其他插件前面。
点赞 3
2026-02-15 15:04
慕容秀云
问题出在静态资源的处理上,Vite的SSR确实有点坑。按照规范,你需要确保两个地方配置正确。

首先是vite.config.js,你的配置里少了server.middlewarebase字段。建议加上base: './',这样可以保证生成的资源路径是相对路径而不是绝对路径。

完整配置应该是这样的:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
plugins: [vue()],
base: './', // 关键点
build: {
rollupOptions: {
input: {'app': './index.html'},
output: {
entryFileNames: 'assets/[name]-[hash].js',
chunkFileNames: 'assets/[name]-[hash].js',
assetFileNames: 'assets/[name]-[hash].[ext]'
}
}
}
})


其次,你用的是@edge-runtime那个库,这个库默认不会处理静态资源。你需要手动挂载一个静态资源中间件,比如用connect-static或者直接实现一个简单的静态文件服务逻辑。

大致代码如下:

import sirv from 'sirv';
const serve = sirv('./dist/client', { dev: true });

// 在你的请求处理链里加入这个中间件
serve(req, res, next);


最后记得检查生成的HTML里标签的路径是否正确,应该指向/assets/main-[hash].css这种形式。

总结就是:配置base字段,加上静态资源中间件。折腾SSR确实容易踩坑,慢慢来吧,兄弟。
点赞 11
2026-02-02 07:00