必须同时修改 vite.config.js 的 base 和 Nginx 的 location,否则必然 404;base 仅重写资源路径,不处理路由请求匹配,Nginx 需通过 alias + try_files 将子路由 fallback 到 index.html,并确保 Vue/React Router 的 base 与之完全一致。

必须同时改 vite.config.js 的 base 和 Nginx 的 location,缺一不可,否则必然 404。
为什么只改 vite.config.js 不行
Vite 构建时用 base 重写所有资源路径(js、css、assets),但不处理路由跳转和服务器请求匹配逻辑。浏览器加载 index.html 后,Vue Router 或 React Router 的 History 模式仍会向根路径发请求,Nginx 找不到对应文件就返回 404。
常见错误现象:
- 首页能打开,但刷新任意子路由(如
/admin/users)直接 404 - 控制台报
Failed to load resource: the server responded with a status of 404 (),且路径是/js/xxx.js(没带子目录前缀)
所以:base 解决资源路径,location + try_files 解决路由回退。
vite.config.js 中 base 怎么设才安全
值必须是完整子路径,以 / 开头和结尾,且与 Nginx 的 location 完全一致。
- 若 Nginx 配置
location /my-app/ { ... },则base必须为'/my-app/' - 不能写成
'./my-app'(开发可用,生产构建后资源路径错乱) - 不能漏尾部
/:写成'/my-app'会导致/my-app/assets/xxx.js变成/my-appassets/xxx.js - 多环境建议用
loadEnv读取.env.production,避免硬编码
示例(推荐):
import { defineConfig, loadEnv } from 'vite'
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd())
return {
base: env.VITE_BASE_PATH, // .env.production 中 VITE_BASE_PATH=/my-app/
plugins: [/* ... */]
}
})Nginx location 配置关键点
核心不是 root,而是 alias + try_files,否则静态资源 404 或路由无法 fallback。
-
alias必须指向dist目录的**绝对路径**,且末尾不加/(与root行为相反) -
try_files $uri $uri/ /my-app/index.html中的/my-app/index.html路径要跟base一致 - 如果用
root替代alias,需把dist放在子目录下,例如/var/www/html/my-app/,再配root /var/www/html;+location /my-app/ { ... },但易混淆,不推荐 - 静态资源缓存规则建议单独加在
location ~* \.(js|css|png|...)块里,避免影响 HTML 的缓存行为
正确配置片段:
location /my-app/ {
alias /var/www/my-vue-project/dist/;
try_files $uri $uri/ /my-app/index.html;
}
location ~* \.(js|css|png|jpg|gif|ico|svg|woff2)$ {
expires 30d;
add_header Cache-Control "public, max-age=2592000";
}Vue Router / React Router 的 base 别漏掉
前端路由库默认认为应用部署在根路径,History 模式下必须显式传入 base,否则 router.push('/users') 仍会跳到 https://domain.com/users 而非 https://domain.com/my-app/users。
- Vue Router:
createWebHistory(import.meta.env.VITE_BASE_PATH) - React Router:
<browserrouter basename="{import.meta.env.VITE_BASE_PATH}"></browserrouter> - 值必须和
vite.config.js中的base完全一致(包括开头结尾的/)
最容易被忽略的是:即使用了 Hash 模式(createWebHashHistory()),base 仍需设对,因为 public 目录下的静态资源(如 favicon.ico)也受 base 影响。


















