今天在进行前端项目的 Vercel 部署时遇到了报错。虽然之前部署前端网页没有遇到这个报错,这次主要是因为 Vercel 找不到预期的 dist 文件夹,配置逻辑没对上。
解决完问题后,我产生了一个核心疑惑:为什么 Vercel 一定要找 dist?为什么要 build?
于是我一步步翻阅文档和博客,把相关的构建知识补充学习了一些。
一、部署的逻辑:优先级与配置陷阱
Vercel 的部署流程主要分两步:准备构建环境和执行构建。在第一阶段,它会创建一个虚拟机并克隆代码。(仓库名字只支持小写字母,不支持特殊符号)
关于配置,我之前在 vercel.json 里写好了,但部署还是报错,后来才发现是优先级的问题:仪表盘设置 > vercel.json 文件 > 框架默认值。
之前我只改了代码里的配置,仪表盘的设置覆盖了它,但是Vercel 依然按默认的根目录去寻找 dist。
二、浏览器工作原理与静态资源哈希化
为什么不能直接把源码丢给浏览器?
因为浏览器本身无法直接高效执行开发环境下的源码(如 TypeScript、JSX 等)。
它需要一个“二次编译”的过程,也就是构建工具的任务。
我之前的理解是:资源哈希化是为了方便 URL 解析。实际上还与精细化的缓存控制相关。如果文件始终叫 image.png,即使内容改了,浏览器因为缓存机制(Cache-Control)也会读取旧文件。构建工具生成的哈希指纹(如 image.a1b2c3.png),改变了文件的 URL,迫使浏览器必须重新发起网络请求。这样每个版本的发布都是独一无二的。
三、源码到部署的“翻译”全链路
我现在大概认识的构建链条是:
- Source Code(源码): 我们在本地写的 TypeScript 等代码。
- 构建工具(Vite): 扮演“中间层”翻译,负责代码转译、模块打包、资源优化。
- Dist(构建产物): 编译好的生产环境代码,包含了静态
assets和server functions。 - Vercel/CDN: 负责读取
dist,按照 Build Output API 定义的规则,将静态文件分发到全球边缘网络。
浏览器本质上是一个“资源请求者”,它通过 URL 获取资源。开发阶段可以用相对路径,但生产环境下,必须经过构建工具将源码映射为 CDN 能够理解的路径规则,这就是为什么要 build 的根本原因。
四、pnpm run build 到底做了什么?
pnpm run build 本质就是调用 Vite 进行一次“生产级转换”。它通过 tsc 进行类型检查,再通过 Vite 的 Pipeline(资源流水线)处理 assets:
- 重命名(哈希化): 应对缓存,确保更新及时。
- 压缩(Minification): 剔除多余代码,优化体积,提升传输速度。
- 内联(Inline)处理: 对于小图标,Vite 会通过
inlineLimit将其转为 Base64 直接嵌入 JS 代码中,这能有效减少 HTTP 请求,避免建立 TCP/TLS 连接的开销,从而提升首屏加载速度。
这一块详情还是看文档,我没有细看太多。
五、从 Webpack 到 Vite:资源处理的进化
对比以前的 Webpack,它处理资源往往需要手动配置 file-loader 等插件,非常繁琐。Vite内置了对资源的智能处理。比如 inlineLimit 参数,它能自动判断文件大小,决定是生成独立文件还是内联。
六、总结与收获
Vite 帮我完成了代码翻译、优化、资源图构建等复杂工作,让我体会到了构建工具作为“中间层”的高效。理解“构建产物是如何生成的”以及“为什么要配置好输出目录”,是今天最大的收获。解决这次报错,不仅是学会了 Vercel 的优先级规则,更重要的是构建起了对前端工程化链路的认知:构建工具是源码与机器解析之间的“桥梁”。通过这次复盘,我明白了以后遇到报错,不仅要看日志,更要通过构建工具输出的 dist 目录去反推链路。