第五章:代码运行的三种状态与构建原理
序言
你听隔壁公司的一位实习生讲了个故事。他第一天上班,leader 让他在本地准备一个演示。他兴冲冲地运行了 pnpm dev,一切正常。
但当 leader 问:"这个本地演示我也能看看吗?" 实习生才发现——leader 的电脑上没有他的数据库配置,而且 Dev 模式也不适合用来演示。
leader 告诉他:"本地开发用的是 Dev 模式,方便你调试。但给用户看的,应该先 pnpm build 构建出生产版本,然后部署到服务器上。"
实习生这才明白,原来代码有不同的运行环境:本地开发用 Dev,给用户看的是 Build 后部署到服务器上的版本。你听着这个故事,觉得这章得好好学学。
三种状态
随着开发的深入,老师傅特意给你科普了代码的三种生命状态,以避免你混淆。
首先是 Dev(开发模式),就是你平时用的 pnpm dev。它就像是打草稿。在这个模式下,当你修改代码并保存后,浏览器不需要刷新整个页面,只会替换改动的那一小块组件。这意味着如果你正在填写一个长长的表单,改了样式后,表单里填好的内容不会丢失。但代价是运行速度较慢,且包含了大量用于报错的调试信息。
其次是 Build(构建模式),当你准备上线时,需要运行 pnpm build。这个过程就像是把草稿排版印刷成书。它会把你写的所有 TypeScript、React 代码进行压缩、优化、翻译,最终在项目中生成一个 .next(或 dist)文件夹。这里面的代码体积极小、运行极快,是专门给用户看的正式版。
最后是 Production(生产模式),运行 pnpm start(或 next start)。这是在本地模拟正式上线的环境,用来运行刚才 build 生成的"正式版"。通常在上线前,你会用这个模式最后检查一遍有没有 Bug。
保存即生效
你可能好奇:为什么在 Dev 模式下保存文件,浏览器会自动刷新?这叫热重载(Hot Reload)。
开发工具会在后台监听文件变化。一旦检测到修改,就会自动刷新浏览器或只更新改动的部分。这让你不需要每次都手动刷新,开发效率大幅提升。
而在 Build 或 Production 模式下,代码已经打包优化,没有这个监听机制,所以修改后需要重新构建。理解这个区别,你就知道为什么有时候改了代码没效果——可能是在错误的模式下运行。
package.json
这时候,你可能会疑惑:为什么输入 pnpm dev 就能启动项目? 老师傅让你打开根目录下的 package.json 文件。他告诉你,这是 Node.js 项目的核心配置文件,管理着项目的元数据、脚本和依赖。
脚本管理 (Scripts):在
scripts字段中,定义了项目常用的运行命令。当你在终端输入pnpm dev时,包管理器会查表,发现它对应的是next dev命令并执行它。这就是为什么复杂的底层命令可以被简化成短短的dev或build。老师傅顺便提了一嘴,这里也是自定义"房间号"的地方。 还记得第一章那个烦人的端口占用吗?你完全可以在这里把命令修改为next dev -p 4000。这样,下次你运行pnpm dev时,应用就会直接在 4000 端口启动,彻底避开拥挤的 3000 端口。依赖管理 (Dependencies):
dependencies列表明确记录了项目运行所必须安装的第三方库(如 React, Next.js, Drizzle)及其具体版本号。这确保了其他人(或服务器)获取代码后,可以通过pnpm install安装一模一样的库,完美还原你的开发环境。
构建产物
构建完成后,你试图在文件夹里找一个 index.html 双击打开,就像第一章做的那样。老师傅告诉你构建产物在 .next(或者 dist)文件夹,但你翻遍了 .next 文件夹,只看到了一堆乱码般的 .js 和 .json 文件。老师傅告诉你,本教程使用的 Next.js 全栈框架,本质上是一个运行在 Node.js 上的"程序",而不是简单的"文件"。它需要连接数据库、处理 API 请求、在服务端渲染页面,这些都离不开服务器环境的支持。
当然,有些场景下你也可以开发纯静态项目(比如使用 Vite + Vue/React),这种项目打包后确实会在 dist 文件夹生成一个 index.html。但为了带你走完数据库、鉴权等完整的全栈流程,我们选择了 Next.js。不过要记住,即使是 Vite 打包出的纯静态文件,通常也不能直接双击打开。因为现代应用使用绝对路径(如 /assets/app.js)引用资源,而双击打开使用的是 文件协议(file:///),这会导致浏览器找不到资源。
所以,请记住:永远不要直接双击打开构建后的代码文件,永远通过 Web 服务器(如 Next.js 的 pnpm start 或 Vite 项目的 pnpm preview)来访问你的应用。
缓存
前面说过,Dev 模式有热重载,改代码保存后浏览器会自动更新,一般不会有缓存问题。
但在 Production 模式(运行 pnpm start)或访问已部署的网站时,你可能会遇到浏览器缓存导致的怪事。比如你把按钮从蓝色改成红色,重新 pnpm build 后访问,按钮依然是蓝色的。你崩溃了,以为进入了平行宇宙。
原来,浏览器为了加载更快,把旧的 CSS/JS 文件存在了本地。你学会了三个大招:一是强制刷新(按住 Ctrl + Shift + R);二是打开浏览器无痕模式;三是打开 F12 开发者工具,在 Network 选项卡里勾选 "Disable cache"。
如果强制刷新还不行,可能是构建缓存的问题,需要删除 .next 目录后重新 pnpm run build。
还有一个经常被忽略的坑:修改了 .env 文件后必须重启服务(Ctrl+C 然后 npm run dev),环境变量才会生效。【详见第6章】 会详细解释为什么环境变量在进程启动时加载,运行中修改文件不会自动更新。
章节导航
- 5.1 缓存陷阱排查 (./01-缓存陷阱排查.md) 🔴
- 5.2 三种运行模式 (./02-三种运行模式.md) 🟢
- 5.3 package.json 实用指南 (./03-package.json实用指南.md) 🟢
- 5.4 构建产物与 Web 服务器 (./04-构建产物与Web服务器.md) 🟢