当前位置: 首页 > news >正文

Nuxt 3 项目实战:从零搭建到生产环境部署全流程

1. 环境准备与项目初始化

第一次接触Nuxt 3时,我像大多数新手一样被它的高效所震撼,但也踩了不少坑。记得那天下午,我对着报错信息折腾了整整三小时才把项目跑起来。现在把这些经验整理出来,帮你避开我走过的弯路。

Node.js版本是第一个拦路虎。Nuxt 3要求Node.js版本≥18.0,但很多人的开发机可能还停留在Node 16甚至更早版本。建议直接安装最新的LTS版本(目前是20.x),用以下命令检查版本:

node -v

如果版本不符,推荐使用nvm(Mac/Linux)或nvm-windows(Windows)管理多版本Node。这是我常用的切换命令:

nvm install 20 nvm use 20

网络问题可能是第二个坑。由于某些CDN域名解析问题,初始化项目时可能会卡在下载模板阶段。我在北京和上海的服务器上都遇到过这个问题,解决方案是在hosts文件添加:

185.199.109.133 raw.githubusercontent.com

Windows用户注意:hosts文件位于C:\Windows\System32\drivers\etc\,修改需要管理员权限。Mac/Linux用户在终端输入:

sudo nano /etc/hosts

现在可以正式初始化项目了。推荐使用nuxi这个官方脚手架工具,它能自动生成最优项目结构:

npx nuxi@latest init my-project

执行后会让你选择包管理器。个人推荐pnpm,它的磁盘占用比npm小60%,安装速度也更快。如果遇到选择困难,不妨试试这个组合命令:

npx nuxi@latest init my-project --packageManager=pnpm

初始化完成后,用VS Code打开项目,你会看到这样的目录结构:

my-project/ ├── .nuxt/ # 构建生成文件 ├── node_modules/ # 依赖包 ├── public/ # 静态资源 ├── server/ # 服务器相关 ├── app.vue # 根组件 └── nuxt.config.ts # 配置文件

2. 项目结构与核心配置

很多新手会困惑Nuxt 3的目录结构到底该怎么组织。经过五个项目的实战,我总结出一套高效目录方案:

src/ ├── assets/ # 需要编译的静态文件 │ └── scss/ │ └── global.scss ├── components/ # 公共组件 │ └── ui/ │ └── Button.vue ├── composables/ # 组合式函数 │ └── useFetchData.ts ├── pages/ # 自动生成路由 │ ├── index.vue │ └── blog/ │ └── [slug].vue └── utils/ # 工具函数 └── date.ts

路由系统是Nuxt 3的亮点。只要在pages目录下创建.vue文件,就会自动生成对应路由。比如:

  • pages/index.vue/
  • pages/about.vue/about
  • pages/blog/[slug].vue/blog/xxx(动态路由)

app.vue中只需要保留最简结构:

<template> <NuxtPage /> </template>

全局样式配置是个高频需求。先在assets/scss下创建global.scss,然后在nuxt.config.ts中添加:

export default defineNuxtConfig({ css: ['~/assets/scss/global.scss'], vite: { css: { preprocessorOptions: { scss: { additionalData: '@use "~/assets/scss/_variables.scss" as *;' } } } } })

3. 开发实战技巧

数据获取是每个项目都绕不开的话题。Nuxt 3提供了四种方式:

  1. useAsyncData - 客户端获取
  2. useFetch - 简化版useAsyncData
  3. $fetch - 基于ohmyfetch的HTTP客户端
  4. useLazyFetch - 懒加载版本

这是我的常用模式:

<script setup> const { data: posts } = await useFetch('/api/posts', { pick: ['title', 'excerpt'], transform: (data) => data.filter(item => item.published) }) </script>

SEO优化需要关注这几个配置:

// nuxt.config.ts export default defineNuxtConfig({ app: { head: { titleTemplate: '%s - 我的网站', meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' } ] } } })

在页面组件中还可以动态设置:

<script setup> useHead({ title: '文章详情', meta: [ { name: 'description', content: '这是文章详情页' } ] }) </script>

性能优化方面,我强烈推荐开启以下配置:

// nuxt.config.ts export default defineNuxtConfig({ nitro: { compressPublicAssets: true, }, experimental: { payloadExtraction: true, inlineSSRStyles: true } })

4. 生产环境部署

打包构建是上线前的最后一步:

npm run build

这会生成.output目录,里面包含:

.output/ ├── public/ # 静态资源 ├── server/ # 服务端代码 └── nitro.json # 服务配置

方案一:直接Node运行

上传.output目录到服务器后:

node ./output/server/index.mjs

这种方式的缺点是进程容易挂掉,适合临时测试。我在内网演示环境经常这么用。

方案二:PM2集群模式

先全局安装PM2:

npm install -g pm2

创建ecosystem.config.js:

module.exports = { apps: [{ name: 'my-nuxt-app', script: './output/server/index.mjs', instances: 'max', exec_mode: 'cluster', env: { NITRO_PORT: 3000, NODE_ENV: 'production' } }] }

启动命令:

pm2 start ecosystem.config.js

Nginx反向代理配置示例:

server { listen 80; server_name example.com; location / { proxy_pass http://localhost:3000; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }

记得重载Nginx配置:

nginx -s reload

监控与维护方面,这些PM2命令很实用:

# 查看日志 pm2 logs my-nuxt-app # 开机自启 pm2 startup pm2 save # 性能监控 pm2 monit

在阿里云ECS上部署时,我发现内存经常吃紧。后来通过配置PM2的max_memory_restart参数解决了问题:

// ecosystem.config.js module.exports = { apps: [{ // ... max_memory_restart: '1G', max_restarts: 5 }] }
http://www.cnnetsun.cn/news/1475485.html

相关文章:

  • 从设计到仿真:基于SolidWorks与MATLAB的6自由度焊接机器人运动学建模全流程解析
  • ValveResourceFormat:突破Source 2资源壁垒的深度解析方案
  • 如何解决AList项目中蓝奏云优享版挂载问题的三个关键步骤
  • 【 每天学习一点算法 2026/03/25】在排序数组中查找元素的第一个和最后一个位置
  • 从零开始使用Materialize打造专业PBR材质:完整指南
  • 半导体假芯片泛滥现状与鉴别防控策略
  • Zabbix虚拟机安装避坑指南:从镜像下载到控制台访问的全流程解析
  • Clawdbot汉化版实际效果:Telegram Bot用--thinking high完成技术选型报告(含对比表格)
  • USB接口全解析:从Type-A到Type-C,教你如何一眼识别并正确使用
  • 从零实现Seq2Seq翻译模型:GRU与Attention机制深度解析
  • 拼多多商家必看:如何用百度指数+AI生成技术自动优化商品标题(附实战案例)
  • 保姆级教程:用STC89C52单片机解码红外遥控器(附NEC协议解析代码)
  • vLLM实战:如何将本地已下载的Yi-1.5-6B模型跑起来(离线部署指南)
  • Gemini 3.0 Pro实战:我用它两分钟‘搓’了个网页版MacOS,附完整提示词和代码
  • 实战教程:用Dify和TF-IDF提升RAG检索效果(附Python代码)
  • LFM2.5-1.2B-Thinking-GGUF部署教程:适配Jetson Orin等边缘GPU完整流程
  • 手把手教程:用Chainlit快速搭建Qwen2.5-VL智能看图助手
  • Prometheus UI 核心页面功能详解与实战场景指南
  • 解密书匠策AI:论文开题报告的“智慧导航仪”
  • Preact日期时间选择器实战:零配置无缝集成pickadate.js全指南
  • SQL SERVER2022用户创建与权限配置实战指南
  • 当传统OCR撞上多模态AI:如何用dots.ocr解决复杂文档解析难题
  • Apache Superset API实战手册:从问题解决到企业集成
  • OpenClaw 2026.3.23:安全、插件、生态三重升级,AI助手进入新纪元
  • 粒子群算法调参避坑指南:惯性权重和学习因子到底怎么设?看这篇就够了
  • 年仅41岁,痛别张雪峰老师:“人生真好玩,下辈子还来”
  • 如何快速实现浏览器自动化:n8n-nodes-puppeteer完整指南
  • JIT加速失效?Python 3.15默认禁用真相,5行代码强制激活+3类函数编译阈值调优,立即提速
  • 从Rhino到UE5:利用Datasmith实现工业设计模型的高保真实时可视化
  • COMSOL注浆模拟:探索微裂隙土体中的浆液注入奥秘