Umi 4 子目录部署:base 配置后路由跳转、静态资源和接口请求三类 404 的排查与修复
【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umi
当你在 Umi 4.x 项目的config.ts里加上base: '/admin'之后,通常会遇到三种现象:页面跳转后 URL 少了/admin前缀直接 404,图片和 JS 资源加载失败,以及接口请求打到了错误的地址。这篇文章按"先判断问题出在哪、再分场景修复"的顺序,给出路由、静态资源、接口请求三类的最小可用做法,读完可以直接对照自己的项目改配置。
base 和 publicPath 管什么、如何配对
base决定路由前缀:配置base: '/admin'后,原来的/和/users分别变成/admin和/admin/users访问。它只在构建时生效,改动后必须重新构建,所以开发和生产环境的 base 要保持一致。
publicPath决定静态资源(JS、CSS、图片)的加载前缀,默认是/。如果路由挂在/admin下而资源仍从站点根目录加载,部署到子目录时就会整片 404。两者配对的判断标准很简单:
- 两者前缀一致,都是
/admin/ - 都以
/结尾(/admin和/admin/不是一回事) - 部署目录结构与它们描述的层级一致
export default { base: '/admin/', publicPath: '/admin/', routes: [{ path: '/', component: 'index' }], };官方示例 examples/ssg-basename/ 里就是base与publicPath同步写法的参考;只想看 base 单独生效的场景可以看 examples/ssr-basename/。
出现 404 时的三个关键检查点
遇到"路由跳转 404"先别改代码,按顺序检查这三处,能覆盖绝大多数情况:
- 当前 URL 有没有 base 前缀。手动访问时如果地址栏是
/admin/about却跳到了/about,说明跳转方式绕过了路由系统(常见于手写了<a href>)。 - 资源请求的路径前缀对不对。打开开发者工具看 404 的具体 URL:如果是
/umi.js而不是/admin/umi.js,问题在publicPath,不在路由。 - 接口和路由是否混用了前缀。接口 404 但页面能打开,说明是请求路径没拼上 base,属于第三类问题,和路由配置无关。
这三个检查点把"一个 404"拆成三种不同的病,后面的修复才有的放矢。
路由跳转:用 Link 组件和 history,而不是原生 a 标签
base 生效后,框架内部的Link组件和historyAPI 会自动补上前缀,只有绕过它们直接操作 URL 才会出问题。
import { Link, history } from 'umi'; // <a href="/about"> 在 base 下会丢前缀,改成: <Link to="/about">关于</Link> // 编程式跳转同理 history.push('/about');<a>标签的href是浏览器直接解析的绝对路径,框架没有任何机会介入,所以它永远不会带上 base。如果你不方便全局替换成Link,也可以在构建产物层面确认前缀是否正确注入。Link的实现可以在 packages/renderer-react/src/link.tsx 里对照阅读,它只是对 react-router 的Link做了预加载增强,路径处理逻辑与 base 是联动的。
静态资源路径怎么写:public 目录和 import 两种走法
静态资源 404 的核心原因是引用方式没经过构建系统。两种可靠的写法:
// 走构建:import 后拿到的是带 publicPath 的完整地址 import logo from './logo.png'; <img src={logo} alt="logo" />- 放在
src里、需要被 webpack/构建工具处理的资源,一律import,不要写./logo.png这种相对路径进src属性 - 放在
public目录、不需要处理的资源,用绝对路径/logo.png书写,构建时会自动拼上publicPath - 样式文件里引用资源时,用
@别名指向 src 目录,避免相对路径在 base 下错位
样式中资源前缀单独控制的场景,publicPath相关的配置说明可以查 docs/docs/api/config.md 的对应章节,具体字段名以官方文档为准。
接口请求路径:前缀统一交给请求实例处理
接口 404 时,先确认一件事:接口路径到底需不需要 base 前缀。多数项目的接口是独立于页面路由部署的,接口路径反而不应该拼 base,此时该用的是proxy(仅 dev 生效)或正确的baseURL,而不是改 base 配置。
// 统一前缀收敛到 request 实例上,调用处保持干净 const apiRequest = request.extend({ prefix: '/api', baseURL: '/api', }); apiRequest('/user/list');开发环境建议用 proxy 把/api转发到真实后端,生产环境靠部署层(nginx 之类)做同样的转发,两边规则保持一致,就能避免"开发正常、上线就错"的差异。仓库里 examples/config-proxy/ 是一个 proxy 配置的最小示例,可以作为起手套路。
修复后的验证清单
改完后按这个顺序过一遍,全部通过才算修好:
- 生产地址带
/admin/前缀能打开首页,不带前缀的行为符合你的部署预期 - 用
Link和history.push各跳一次页,地址栏前缀不丢失 - 开发者工具 Network 里刷新一次,所有 JS/CSS/图片请求都带
/admin/前缀且返回 200 - 接口请求在 dev 和 production 下指向同一个后端地址(一个走 proxy、一个走部署层转发)
- 如果同时改了 base 或 publicPath,确认重新执行过构建——base 内联在客户端包里,热改配置不生效
⚠️ 最容易漏的最后一条:base 改动必须重新构建,只重启 dev 进程不够。
如果三个检查点都通过仍有个别 404,把 404 的完整 URL 贴出来对照publicPath判断归属,通常能立刻定位到是路由、资源还是请求这一类。
【免费下载链接】umiA framework in react community ✨项目地址: https://gitcode.com/GitHub_Trending/um/umi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考