前两节解决了"为什么"与"是什么",本节动手把跑道铺好:从 Node 环境检查到项目初始化、目录速览、开发服务器、生产构建与预览。这个项目就是后面八章的实验场——第 2 章会逐目录拆解它,第 3 章往里加数据获取,第 6 章往里写接口。
Nuxt 3 对 Node 版本有硬性要求(官方推荐使用 LTS 版本,至少需支持原生 ESM 与现代构建工具链)。开工前先确认版本:
# 检查 Node 版本,建议 18 或更高的 LTS 版本 node -v # 输出示例:v20.11.0 # 版本过低时用 nvm 切换(已安装 nvm 的环境) nvm install 20 nvm use 20
初始化项目只需一条命令:
# 在目标目录执行,nuxt-app 替换为你的项目名 npx nuxi@latest init nuxt-app
命令会询问包管理器偏好(npm / pnpm / yarn)与是否初始化 Git 仓库。完成后进入目录安装依赖并启动:
cd nuxt-app npm install npm run dev
几秒后终端输出类似下面的信息:
Nuxt 3.13.0 with Nitro 2.9.0 ➜ Local: http://localhost:3000/ ➜ Network: use --host to expose
注意这个启动速度——Vite 驱动的开发服务器不做全量打包,冷启动通常在几秒内,这直接改善了日常开发的体感。浏览器打开本地地址,能看到默认欢迎页即环境就绪。
初始化完成的项目小得令人意外,核心只有几个文件:
nuxt-app/ ├── app.vue # 应用入口组件 ├── nuxt.config.ts # 全局配置 ├── package.json # 依赖与脚本 ├── public/ # 静态资源原样拷贝 ├── server/ # 服务端代码(API、中间件) └── tsconfig.json # TypeScript 配置
app.vue 默认只有十行左右,渲染欢迎页。试着做第一个修改——把 app.vue 整个替换为:
<template> <div style="max-width: 640px; margin: 80px auto; font-family: sans-serif"> <h1>接力赛起跑线</h1> <p>首屏这段文字由服务器渲染,查看网页源代码能直接看到它。</p> <button @click="count++">接棒后我是交互:点了 {{ count }} 次</button> </div> </template> <script setup> const count = ref(0) </script>
保存后浏览器即时热更新。现在做本节最重要的一步验证:右键"查看网页源代码",在 HTML 里搜索"接力赛起跑线"——你会直接找到这段文字。这就是 1.1 说的服务器第一棒:内容在首份 HTML 里,而不是等 JavaScript 到场后才出现。而按钮的计数功能,由浏览器水合后接管,属于第二棒。
顺带注意 ref 这个 API——代码里没有一行 import。这是 Nuxt 的自动导入机制,ref、computed、useRoute 等常用 API 全局可用,第 2 章会拆解它的规则与边界。
开发服务器只是日常,最终产物要经过构建。打开 package.json 看脚本:
{ "scripts": { "build": "nuxt build", "dev": "nuxt dev", "generate": "nuxt generate", "preview": "nuxt preview", "postinstall": "nuxt prepare" } }
依次体验三个关键命令:
# 生产构建:产出 .output 目录,包含 Node 服务器与静态资源 npm run build # 输出末尾会提示:You can preview this build using node .output/server/index.mjs # 本地预览生产构建(真实模拟线上行为) npm run preview # 终端输出:Listening on http://localhost:3000/ # 或直接以 Node 运行产物 node .output/server/index.mjs
构建产物值得打开看一眼:.output/server 是可独立运行的 Node 服务器,.output/public 是浏览器侧静态资源。Nuxt 3 的 Nitro 引擎把"同一份代码编译到多个运行时"做成了构建目标切换——想部署成 Serverless 函数或边缘worker,改一个预设参数重新构建即可,第 6 章与第 9 章会用到这个能力。
再试一次 SSG:
# 静态生成:把当前应用输出为纯静态站点 npm run generate # 产物在 .output/public,任意静态服务器可托管
同一个项目,build 得到带服务器的全栈产物,generate 得到纯静态文件——1.2 讲的"模式是属性不是宿命",在这里第一次落到命令行层面。
⚠️ 常见坑:把
npm run preview当成开发环境用。preview 跑的是生产构建,没有热更新与详细报错,改了代码也看不到效果。日常开发认准npm run dev。
💡 关键直觉:dev、build、generate、preview 四条命令对应接力赛的不同阶段——dev 是训练场(热更新、详细报错),build 是正式装备(可部署产物),generate 是把整场赛事提前录好(静态文件),preview 是赛前彩排(生产模式本地验证)。
npm run postinstall(即 nuxt prepare)生成类型声明,编辑器重启后生效。nuxi init 初始化、npm run dev 启动,Vite 让冷启动进入秒级;ref 等 API 无需 import,机制细节在 2.1 展开;.output/server 是 Node 服务器,.output/public 是静态资源,多运行时部署的基础在 Nitro。