Skip to content

Vue.js 项目部署

构建生产版本

Vite 项目

bash
# 构建
npm run build

# 预览构建结果
npm run preview

构建后的文件在 dist 目录中。

环境变量

bash
# .env.production
VITE_API_URL=https://api.production.com
VITE_APP_TITLE=My App
javascript
// 使用环境变量
const apiUrl = import.meta.env.VITE_API_URL

静态托管平台

1. Vercel(推荐)

特点:

  • 零配置部署
  • 自动 HTTPS
  • 全球 CDN
  • 自动预览部署

部署步骤:

bash
# 安装 Vercel CLI
npm i -g vercel

# 登录
vercel login

# 部署
vercel

# 生产部署
vercel --prod

或通过 GitHub 集成:

  1. 访问 vercel.com
  2. 导入 GitHub 仓库
  3. 自动部署

2. Netlify

部署步骤:

bash
# 安装 Netlify CLI
npm install -g netlify-cli

# 登录
netlify login

# 部署
netlify deploy

# 生产部署
netlify deploy --prod

配置文件:

toml
# netlify.toml
[build]
  command = "npm run build"
  publish = "dist"

[[redirects]]
  from = "/*"
  to = "/index.html"
  status = 200

3. GitHub Pages

部署脚本:

bash
#!/usr/bin/env sh

# 构建
npm run build

# 进入构建目录
cd dist

# 初始化 git
git init
git add -A
git commit -m 'deploy'

# 推送到 gh-pages 分支
git push -f git@github.com:username/repo.git master:gh-pages

cd -

Vite 配置:

javascript
// vite.config.js
export default defineConfig({
  base: '/repo-name/',  // GitHub Pages 子路径
  plugins: [vue()]
})

4. Cloudflare Pages

  1. 登录 Cloudflare Pages
  2. 连接 GitHub 仓库
  3. 配置构建命令:npm run build
  4. 配置输出目录:dist
  5. 部署

服务器部署

Nginx 配置

nginx
server {
    listen 80;
    server_name example.com;
    root /var/www/app/dist;
    index index.html;

    # Gzip 压缩
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    # 缓存静态资源
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }

    # SPA 路由支持
    location / {
        try_files $uri $uri/ /index.html;
    }

    # API 代理
    location /api {
        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;
    }
}

Docker 部署

Dockerfile:

dockerfile
# 构建阶段
FROM node:18-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# 生产阶段
FROM nginx:alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

docker-compose.yml:

yaml
version: '3.8'
services:
  web:
    build: .
    ports:
      - "80:80"
    restart: always

构建和运行:

bash
# 构建镜像
docker build -t my-vue-app .

# 运行容器
docker run -d -p 80:80 my-vue-app

# 使用 docker-compose
docker-compose up -d

Node.js 服务器

Express 服务器

javascript
// server.js
import express from 'express'
import { fileURLToPath } from 'url'
import { dirname, join } from 'path'

const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)

const app = express()
const port = process.env.PORT || 3000

// 静态文件
app.use(express.static(join(__dirname, 'dist')))

// SPA 路由支持
app.get('*', (req, res) => {
  res.sendFile(join(__dirname, 'dist', 'index.html'))
})

app.listen(port, () => {
  console.log(`Server running at http://localhost:${port}`)
})

package.json:

json
{
  "scripts": {
    "start": "node server.js",
    "build": "vite build"
  }
}

CDN 加速

使用 CDN 托管静态资源

javascript
// vite.config.js
export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        // 分离 vendor
        manualChunks: {
          'vue-vendor': ['vue', 'vue-router', 'pinia']
        }
      }
    }
  },
  // 使用 CDN
  base: 'https://cdn.example.com/'
})

常用 CDN 服务

  • jsDelivr:免费、快速
  • unpkg:npm 包 CDN
  • cdnjs:流行库 CDN
  • 阿里云 CDN:国内访问快
  • 腾讯云 CDN:国内访问快

性能优化

1. 代码分割

javascript
// 路由懒加载
const routes = [
  {
    path: '/about',
    component: () => import('./views/About.vue')
  }
]

2. 压缩和混淆

javascript
// vite.config.js
export default defineConfig({
  build: {
    minify: 'terser',
    terserOptions: {
      compress: {
        drop_console: true,
        drop_debugger: true
      }
    }
  }
})

3. Gzip 压缩

bash
npm install -D vite-plugin-compression
javascript
// vite.config.js
import viteCompression from 'vite-plugin-compression'

export default defineConfig({
  plugins: [
    vue(),
    viteCompression({
      algorithm: 'gzip',
      ext: '.gz'
    })
  ]
})

4. 图片优化

bash
npm install -D vite-plugin-imagemin
javascript
// vite.config.js
import viteImagemin from 'vite-plugin-imagemin'

export default defineConfig({
  plugins: [
    vue(),
    viteImagemin({
      gifsicle: { optimizationLevel: 7 },
      optipng: { optimizationLevel: 7 },
      mozjpeg: { quality: 80 },
      svgo: {
        plugins: [
          { name: 'removeViewBox', active: false }
        ]
      }
    })
  ]
})

监控和分析

1. 性能监控

javascript
// main.js
if ('performance' in window) {
  window.addEventListener('load', () => {
    const perfData = window.performance.timing
    const pageLoadTime = perfData.loadEventEnd - perfData.navigationStart
    console.log('Page load time:', pageLoadTime)
  })
}

2. 错误监控

javascript
// 全局错误处理
app.config.errorHandler = (err, instance, info) => {
  console.error('Global error:', err)
  // 发送到错误监控服务
  // sendToErrorTracking(err, info)
}

// 未捕获的 Promise 错误
window.addEventListener('unhandledrejection', event => {
  console.error('Unhandled promise rejection:', event.reason)
})

3. 使用 Sentry

bash
npm install @sentry/vue
javascript
// main.js
import * as Sentry from '@sentry/vue'

Sentry.init({
  app,
  dsn: 'YOUR_SENTRY_DSN',
  integrations: [
    new Sentry.BrowserTracing({
      routingInstrumentation: Sentry.vueRouterInstrumentation(router)
    })
  ],
  tracesSampleRate: 1.0
})

CI/CD 自动化

GitHub Actions

yaml
# .github/workflows/deploy.yml
name: Deploy

on:
  push:
    branches: [ main ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'
        
    - name: Install dependencies
      run: npm ci
      
    - name: Build
      run: npm run build
      
    - name: Deploy to Vercel
      uses: amondnet/vercel-action@v20
      with:
        vercel-token: ${{ secrets.VERCEL_TOKEN }}
        vercel-org-id: ${{ secrets.ORG_ID }}
        vercel-project-id: ${{ secrets.PROJECT_ID }}
        vercel-args: '--prod'

GitLab CI

yaml
# .gitlab-ci.yml
stages:
  - build
  - deploy

build:
  stage: build
  image: node:18
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/

deploy:
  stage: deploy
  script:
    - echo "Deploying to production"
    # 部署脚本
  only:
    - main

域名和 HTTPS

1. 配置域名

在域名提供商处添加 DNS 记录:

A    @    your-server-ip
CNAME www  your-domain.com

2. 配置 HTTPS

使用 Let's Encrypt 免费证书:

bash
# 安装 Certbot
sudo apt-get install certbot python3-certbot-nginx

# 获取证书
sudo certbot --nginx -d example.com -d www.example.com

# 自动续期
sudo certbot renew --dry-run

部署检查清单

构建前

  • ✅ 移除 console.log
  • ✅ 检查环境变量
  • ✅ 更新依赖版本
  • ✅ 运行测试
  • ✅ 检查构建警告

部署后

  • ✅ 检查所有页面是否正常
  • ✅ 测试路由跳转
  • ✅ 检查 API 调用
  • ✅ 测试表单提交
  • ✅ 检查移动端适配
  • ✅ 测试不同浏览器
  • ✅ 检查 SEO 标签
  • ✅ 测试性能指标

监控

  • ✅ 设置错误监控
  • ✅ 配置性能监控
  • ✅ 设置日志收集
  • ✅ 配置告警通知

常见问题

1. 刷新 404

原因:服务器没有配置 SPA 路由支持

解决:配置服务器将所有请求重定向到 index.html

2. 静态资源 404

原因:base 路径配置错误

解决:检查 vite.config.js 中的 base 配置

3. 环境变量不生效

原因:环境变量名称错误或未重新构建

解决:确保变量名以 VITE_ 开头,重新构建

总结

  • 选择合适的托管平台(Vercel、Netlify、GitHub Pages)
  • 配置服务器支持 SPA 路由
  • 使用 Docker 容器化部署
  • 启用 Gzip 压缩和 CDN 加速
  • 配置 HTTPS 和自定义域名
  • 设置 CI/CD 自动化部署
  • 添加监控和错误追踪
  • 优化性能和加载速度

下一步

接下来学习 最佳实践,了解 Vue 开发的最佳实践。