Vue部署踩坑

12.1 Vue打包配置的常见错误

核心知识点

  • Vue打包配置的基本原理
  • webpack配置的常见问题
  • 构建优化的策略

常见错误场景

错误场景1:webpack配置错误

// vue.config.js
module.exports = {
  // 错误:配置了不存在的选项
  configureWebpack: {
    plugins: [
      new webpack.ProvidePlugin({
        $: 'jquery'
      })
    ]
  },
  // 错误:重复配置
  chainWebpack: config => {
    config.plugin('provide').use(webpack.ProvidePlugin, [{
      $: 'jquery'
    }])
  }
}

错误原因:配置了不存在的选项或重复配置,导致构建失败。

正确实现

// vue.config.js
const webpack = require('webpack')

module.exports = {
  configureWebpack: {
    plugins: [
      new webpack.ProvidePlugin({
        $: 'jquery'
      })
    ]
  }
}

错误场景2:生产环境Source Map配置错误

// vue.config.js
module.exports = {
  // 错误:生产环境开启了Source Map
  productionSourceMap: true
}

错误原因:生产环境开启Source Map会增加打包体积,并且可能暴露源代码。

正确实现

// vue.config.js
module.exports = {
  // 正确:生产环境关闭Source Map
  productionSourceMap: false
}

12.2 Vue静态资源路径的陷阱

核心知识点

  • Vue静态资源的处理方式
  • publicPath的配置和使用
  • 静态资源的引用方法

常见错误场景

错误场景1:publicPath配置错误

// vue.config.js
module.exports = {
  // 错误:publicPath配置错误
  publicPath: './'
}

错误原因:publicPath配置错误,可能导致静态资源无法正确加载。

正确实现

// vue.config.js
module.exports = {
  // 正确:根据环境配置publicPath
  publicPath: process.env.NODE_ENV === 'production'
    ? '/my-app/'
    : '/'
}

错误场景2:静态资源引用错误

<template>
  <div>
    <!-- 错误:静态资源引用路径错误 -->
    <img src="@/assets/logo.png" alt="Logo">
    <!-- 错误:public目录下的资源引用错误 -->
    <img src="@/public/favicon.ico" alt="Favicon">
  </div>
</template>

错误原因:静态资源引用路径错误,导致资源无法正确加载。

正确实现

<template>
  <div>
    <!-- 正确:src目录下的资源引用 -->
    <img src="@/assets/logo.png" alt="Logo">
    <!-- 正确:public目录下的资源引用 -->
    <img src="/favicon.ico" alt="Favicon">
  </div>
</template>

12.3 Vue环境变量的使用误区

核心知识点

  • Vue环境变量的配置和使用
  • 不同环境的环境变量管理
  • 环境变量的加载顺序

常见错误场景

错误场景1:环境变量命名错误

# .env.production
# 错误:环境变量命名不符合规范
API_URL=https://api.example.com

错误原因:环境变量命名不符合Vue的规范,Vue只能识别以VUE_APP_开头的环境变量。

正确实现

# .env.production
# 正确:使用符合规范的环境变量名
VUE_APP_API_URL=https://api.example.com

错误场景2:环境变量使用错误

// 错误:在代码中直接使用未定义的环境变量
const apiUrl = process.env.API_URL

错误原因:使用了未定义的环境变量,可能导致应用运行错误。

正确实现

// 正确:使用符合规范的环境变量
const apiUrl = process.env.VUE_APP_API_URL
// 正确:提供默认值
const apiUrl = process.env.VUE_APP_API_URL || 'https://default-api.example.com'

12.4 Vue生产环境的优化陷阱

核心知识点

  • Vue生产环境的优化策略
  • 代码分割和懒加载
  • 缓存策略的配置

常见错误场景

错误场景1:没有开启代码分割

// vue.config.js
module.exports = {
  // 错误:没有开启代码分割
}

错误原因:没有开启代码分割,导致打包体积过大,影响首屏加载速度。

正确实现

// vue.config.js
module.exports = {
  // 正确:开启代码分割
  configureWebpack: {
    optimization: {
      splitChunks: {
        chunks: 'all'
      }
    }
  }
}

错误场景2:没有使用路由懒加载

// router/index.js
import Home from '@/views/Home.vue'
import About from '@/views/About.vue'

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
]

错误原因:没有使用路由懒加载,导致初始打包体积过大。

正确实现

// router/index.js
const Home = () => import('@/views/Home.vue')
const About = () => import('@/views/About.vue')

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
]

12.5 Vue部署到不同服务器的问题

核心知识点

  • 不同服务器的部署配置
  • Nginx配置示例
  • Apache配置示例

常见错误场景

错误场景1:Nginx配置错误

# 错误:Nginx配置错误
server {
  listen 80;
  server_name example.com;
  
  location / {
    root /var/www/html;
    index index.html;
  }
}

错误原因:Nginx配置错误,没有处理单页应用的路由问题。

正确实现

# 正确:Nginx配置
server {
  listen 80;
  server_name example.com;
  
  location / {
    root /var/www/html;
    index index.html;
    try_files $uri $uri/ /index.html;
  }
}

错误场景2:Apache配置错误

# 错误:Apache配置错误
<VirtualHost *:80>
  ServerName example.com
  DocumentRoot /var/www/html
</VirtualHost>

错误原因:Apache配置错误,没有处理单页应用的路由问题。

正确实现

# 正确:Apache配置
<VirtualHost *:80>
  ServerName example.com
  DocumentRoot /var/www/html
  
  <Directory /var/www/html>
    AllowOverride All
  </Directory>
</VirtualHost>

# .htaccess
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

12.6 Vue CDN部署的常见错误

核心知识点

  • Vue CDN部署的配置
  • 第三方库的CDN引用
  • 构建配置的调整

常见错误场景

错误场景1:CDN配置错误

// vue.config.js
module.exports = {
  // 错误:CDN配置错误
  configureWebpack: {
    externals: {
      'vue': 'Vue',
      'vue-router': 'VueRouter',
      'axios': 'axios'
    }
  }
}

错误原因:CDN配置错误,没有在HTML中正确引入CDN资源。

正确实现

// vue.config.js
module.exports = {
  configureWebpack: {
    externals: {
      'vue': 'Vue',
      'vue-router': 'VueRouter',
      'axios': 'axios'
    }
  }
}

// public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <link rel="icon" href="<%= BASE_URL %>favicon.ico">
  <title><%= htmlWebpackPlugin.options.title %></title>
  <!-- 正确:引入CDN资源 -->
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.11/dist/vue.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/vue-router@3.2.0/dist/vue-router.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/axios@0.19.2/dist/axios.min.js"></script>
</head>
<body>
  <noscript>
    <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
  </noscript>
  <div id="app"></div>
  <!-- built files will be auto injected -->
</body>
</html>

错误场景2:CDN版本不兼容

<!-- public/index.html -->
<!-- 错误:CDN版本不兼容 -->
<script src="https://cdn.jsdelivr.net/npm/vue@3.0.0/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router@3.2.0/dist/vue-router.min.js"></script>

错误原因:CDN版本不兼容,Vue 3需要使用Vue Router 4。

正确实现

<!-- public/index.html -->
<!-- 正确:使用兼容的CDN版本 -->
<script src="https://cdn.jsdelivr.net/npm/vue@3.0.0/dist/vue.global.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-router@4.0.0/dist/vue-router.global.min.js"></script>

12.7 Vue PWA的配置陷阱

核心知识点

  • Vue PWA的配置和使用
  • service-worker的配置
  • PWA的部署和更新策略

常见错误场景

错误场景1:PWA配置错误

// vue.config.js
module.exports = {
  // 错误:PWA配置错误
  pwa: {
    name: 'My App',
    themeColor: '#4DBA87',
    msTileColor: '#000000',
    appleMobileWebAppCapable: 'yes',
    appleMobileWebAppStatusBarStyle: 'black',
    // 错误:配置了不存在的选项
    manifestOptions: {
      icons: [
        {
          src: './img/icons/android-chrome-192x192.png',
          sizes: '192x192',
          type: 'image/png'
        }
      ]
    }
  }
}

错误原因:PWA配置错误,可能导致PWA功能无法正常工作。

正确实现

// vue.config.js
module.exports = {
  pwa: {
    name: 'My App',
    themeColor: '#4DBA87',
    msTileColor: '#000000',
    appleMobileWebAppCapable: 'yes',
    appleMobileWebAppStatusBarStyle: 'black',
    workboxOptions: {
      exclude: [/\.map$/, /manifest\.json$/]
    }
  }
}

错误场景2:没有正确处理PWA更新

// src/registerServiceWorker.js
import { register } from 'register-service-worker'

if (process.env.NODE_ENV === 'production') {
  register(`${process.env.BASE_URL}service-worker.js`, {
    ready() {
      console.log('App is being served from cache by a service worker.')
    },
    registered() {
      console.log('Service worker has been registered.')
    },
    cached() {
      console.log('Content has been cached for offline use.')
    },
    updatefound() {
      console.log('New content is downloading.')
    },
    // 错误:没有处理更新事件
    updated() {
      console.log('New content is available; please refresh.')
    },
    offline() {
      console.log('No internet connection found. App is running in offline mode.')
    },
    error(error) {
      console.error('Error during service worker registration:', error)
    }
  })
}

错误原因:没有处理PWA更新事件,导致用户无法获取最新版本。

正确实现

// src/registerServiceWorker.js
import { register } from 'register-service-worker'

if (process.env.NODE_ENV === 'production') {
  register(`${process.env.BASE_URL}service-worker.js`, {
    ready() {
      console.log('App is being served from cache by a service worker.')
    },
    registered() {
      console.log('Service worker has been registered.')
    },
    cached() {
      console.log('Content has been cached for offline use.')
    },
    updatefound() {
      console.log('New content is downloading.')
    },
    updated(registration) {
      console.log('New content is available; please refresh.')
      // 正确:提示用户刷新
      document.dispatchEvent(
        new CustomEvent('swUpdated', { detail: registration })
      )
    },
    offline() {
      console.log('No internet connection found. App is running in offline mode.')
    },
    error(error) {
      console.error('Error during service worker registration:', error)
    }
  })
}

12.8 Vue SSR部署的使用误区

核心知识点

  • Vue SSR的部署配置
  • 服务器端和客户端代码的处理
  • SSR的性能优化

常见错误场景

错误场景1:SSR配置错误

// server.js
const { createSSRApp } = require('vue')
const { renderToString } = require('@vue/server-renderer')
const express = require('express')

const app = express()

app.get('*', async (req, res) => {
  // 错误:没有处理错误
  const app = createSSRApp({
    data() {
      return {
        user: {}
      }
    },
    template: `<div>Hello {{ user.name }}</div>`
  })
  
  const html = await renderToString(app)
  res.send(`
    <!DOCTYPE html>
    <html>
      <head>
        <title>Vue SSR</title>
      </head>
      <body>
        <div id="app">${html}</div>
      </body>
    </html>
  `)
})

app.listen(3000)

错误原因:SSR配置错误,没有处理错误情况,可能导致服务器崩溃。

正确实现

// server.js
const { createSSRApp } = require('vue')
const { renderToString } = require('@vue/server-renderer')
const express = require('express')

const app = express()

app.get('*', async (req, res) => {
  try {
    const app = createSSRApp({
      data() {
        return {
          user: {}
        }
      },
      template: `<div>Hello {{ user.name }}</div>`
    })
    
    const html = await renderToString(app)
    res.send(`
      <!DOCTYPE html>
      <html>
        <head>
          <title>Vue SSR</title>
        </head>
        <body>
          <div id="app">${html}</div>
        </body>
      </html>
    `)
  } catch (error) {
    console.error('SSR error:', error)
    res.status(500).send('Internal Server Error')
  }
})

app.listen(3000)

错误场景2:没有正确处理客户端激活

// client.js
const { createApp } = require('vue')

createApp({
  data() {
    return {
      user: {}
    }
  },
  template: `<div>Hello {{ user.name }}</div>`
}).mount('#app')

错误原因:没有正确处理客户端激活,可能导致 hydration 错误。

正确实现

// client.js
const { createApp } = require('vue')

// 确保客户端和服务器端使用相同的应用配置
const app = createApp({
  data() {
    return {
      user: {}
    }
  },
  template: `<div>Hello {{ user.name }}</div>`
})

// 挂载应用
app.mount('#app')
« 上一篇 Vue测试踩坑 下一篇 » Vue工具链踩坑