Vue.js project deployment

Build production version

Vite Project

# 构建
npm run build

# 预览构建结果
npm run preview

The built file is indistin the directory.

Environment variables

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

Static hosting platform

Features:

  • Zero configuration deployment
  • Automatic HTTPS
  • Global CDN
  • Automatic preview deployment

Deployment steps:

# 安装 Vercel CLI
npm i -g vercel

# 登录
vercel login

# 部署
vercel

# 生产部署
vercel --prod

Or integrated via GitHub:

  1. Visit vercel.com
  2. Import GitHub repository
  3. Automatic deployment

2. Netlify

Deployment steps:

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

# 登录
netlify login

# 部署
netlify deploy

# 生产部署
netlify deploy --prod

Configuration file:

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

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

3. GitHub Pages

Deployment script:

#!/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 Configuration:

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

4. Cloudflare Pages

  1. Log in to Cloudflare Pages
  2. Connect to GitHub repository
  3. Configure build commands:npm run build
  4. Configure the output directory:dist
  5. Deployment

Server deployment

Nginx configuration

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 deployment

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:

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

Build and run:

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

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

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

Node.js Server

Express Server

// 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:

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

CDN Acceleration

Use CDN to host static resources

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

Commonly used CDN services

  • jsDelivr: Free and fast
  • unpkg: npm package CDN
  • cdnjs: Popular library CDN
  • Alibaba Cloud CDN: fast domestic access
  • Tencent Cloud CDN: Fast domestic access

Performance optimization

1. Code splitting

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

2. Compression and obfuscation

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

3. Gzip compression

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

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

4. Image optimization

npm install -D vite-plugin-imagemin
// 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 }
        ]
      }
    })
  ]
})

Monitoring and Analysis

1. Performance monitoring

// 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. Error monitoring

// 全局错误处理
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. Using Sentry

npm install @sentry/vue
// 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 Automation

GitHub Actions

# .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

# .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

Domain name and HTTPS

1. Configure domain name

Add DNS records at your domain provider:

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

2. Configure HTTPS

Use Let's Encrypt free certificates:

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

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

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

Deployment Checklist

Before building

  • ✅ Remove console.log
  • ✅ Check environment variables
  • ✅ Update dependency version
  • ✅ Run the test
  • ✅ Check for build warnings

After deployment

  • ✅ Check whether all pages are working properly
  • ✅ Test route jump
  • ✅ Check API calls
  • ✅ Test form submission
  • ✅ Check mobile adaptation
  • ✅ Test different browsers
  • ✅ Check SEO tags
  • ✅ Test performance indicators

Monitoring

  • ✅ Set up error monitoring
  • ✅ Configure performance monitoring
  • ✅ Set up log collection
  • ✅ Configure alarm notifications

FAQ

1. Refresh 404

Cause: The server is not configured with SPA routing support

SOLUTION: Configure the server to redirect all requests to index.html

2. Static resources 404

Cause: Base path configuration error

Solution: Check the base configuration in vite.config.js

3. Environment variables do not take effect

Cause: Wrong environment variable name or not rebuilt

Solution: Make sure the variable name ends withVITE_Beginning, rebuilding

Summarize

  • Choose the right hosting platform (Vercel, Netlify, GitHub Pages)
  • Configure server to support SPA routing
  • Containerized deployment using Docker
  • Enable Gzip compression and CDN acceleration
  • Configure HTTPS and custom domain name
  • Set up CI/CD automated deployment
  • Add monitoring and error tracking
  • Optimize performance and loading speed

Next step

Next, learn Best Practices to learn about the best practices for Vue development.