Code前端首页关于Code前端联系我们

测试环境

terry 3小时前 阅读数 3 #Vue
文章标签 测试 环境

p>前端同学做完 Vue2 项目,部署到 Nginx 时是不是总碰到刷新 404、资源找不到、跨域失败这些问题?其实不是 Nginx 难,是配置细节和项目打包逻辑没对上,这篇从项目打包准备Nginx 配置实操,再到常见坑点解决,一步步讲透,新手也能跟着搞定部署!

Vue2 项目打包前,这些准备工作不能少

很多部署问题,根源在打包阶段,得先把项目配置和路由模式理顺:

路由模式(Hash vs History)的选择

Vue Router 默认是 hash 模式(URL 带 ),这种模式下,打包后部署到 Nginx 基本不用额外配置,因为 后的路径不会传给服务器,但如果想去掉 用 history 模式,服务器必须配合处理路由转发——因为用户直接访问 /about 这类路径时,Nginx 如果没配置,会返回 404。

所以选 history 模式前,得确认:后端是否支持(或 Nginx 能否处理路由 fallback),然后在 router/index.js 里设置:

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL, // 对应 publicPath,打包时要一致
  routes: [...]
})

publicPath 与静态资源路径

Vue CLI 的 vue.config.js 里的 publicPath,决定了打包后静态资源(js、css、img)的引用路径。

  • 如果项目部署在域名根目录(如 https://xxx.com/),publicPath 设为 即可。
  • 如果部署在子路径(如 https://xxx.com/my-app/),必须设为 '/my-app/'(注意末尾的斜杠),否则打包后资源会指向根目录,导致 404。

举个例子,子路径部署时 vue.config.js 配置:

module.exports = {
  publicPath: process.env.NODE_ENV === 'production' ? '/my-app/' : '/',
  outputDir: 'dist', // 打包输出目录
  // ...其他配置
}

Axios 基础路径配置(跨域/接口路径)

如果前端请求后端接口,开发时用 proxy 代理(vue.config.jsdevServer.proxy),生产环境要改接口基础路径,可以用环境变量区分:

.env.production 文件里加:

VUE_APP_API_BASE = 'https://xxx.com/api' // 后端生产环境接口地址

然后在 Axios 封装里:

import axios from 'axios'
const service = axios.create({
  baseURL: process.env.VUE_APP_API_BASE,
  timeout: 5000
})

Nginx 配置核心步骤:把 Vue2 dist 丢进去就能跑?没那么简单

Nginx 的作用是“把静态文件吐给浏览器”+“处理路由/跨域/缓存”,核心是 nginx.conf 或自定义的 server 配置文件,步骤如下:

找到 Nginx 配置文件位置

不同系统位置不同:Linux 通常在 /etc/nginx/nginx.conf,Mac 用 brew 安装的可能在 /usr/local/etc/nginx/nginx.conf,Windows 在安装目录的 conf/nginx.conf

配置 server 块(以部署到根目录,history 模式为例)

打开配置文件,在 http 块里加一个 server

server {
    listen       80; # 监听端口,http 用 80,https 用 443
    server_name  your-domain.com; # 你的域名或 IP
    # 指向 Vue2 打包后的 dist 目录
    root   /usr/local/nginx/html/my-vue2-app/dist; 
    index  index.html index.htm;
    # 处理 history 模式的路由 fallback
    location / {
        try_files $uri $uri/ /index.html; 
        # 尝试找文件→找目录→返回 index.html(让前端路由接管)
    }
    # 静态资源缓存(可选,优化性能)
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
        expires 30d; # 缓存 30 天
        add_header Cache-Control "public, max-age=2592000";
    }
    # 错误页重定向(可选)
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}

关键点解释

  • root:直接指向 dist 目录的绝对路径,要确保 Nginx 有访问权限(Linux 下注意用户组)。
  • try_files:history 模式必配!用户访问 /about 时,Nginx 先找 about 文件/目录,没有就返回 index.html,让 Vue Router 解析路由。
  • location ~* \.(js|css|...)$:对静态资源设置缓存,减少重复请求,但要注意,如果资源没加 hash(Vue CLI 默认的 chunkhash),更新后可能缓存不失效,所以结合打包时的 hash 命名更安全(Vue CLI 已自动处理)。

部署后必踩的 5 个坑,及解决方法

哪怕配置步骤对了,还是可能碰到奇奇怪怪的问题,这 5 个场景几乎人人踩过:

坑 1:刷新页面报 404(history 模式专属)

现象:首页能正常访问,点路由跳转也 ok,但刷新 /about 这类页面,Nginx 返回 404。

原因:Nginx 不认识前端路由,以为 /about 是真实文件/目录,找不到就返回 404。

解决:在 location / 里加 try_files $uri $uri/ /index.html;(前面配置里已经写了,没加的话补上)。

坑 2:静态资源(js/css/img)加载 404

现象:控制台报 net::ERR_ABORTED 404,资源路径不对。

原因分两种

  1. publicPath 配置错误:比如部署在子路径 /my-app/,但 publicPath 设为 ,导致资源路径变成 https://xxx.com/js/app.xxx.js,实际应该是 https://xxx.com/my-app/js/...
    解决:修改 vue.config.jspublicPath'/my-app/',重新打包部署。

  2. Nginx 的 rootalias 用错:

    • root 是“拼接路径”,root /usr/dist,请求 /js/app.js 会找 /usr/dist/js/app.js
    • alias 是“替换路径”,alias /my-app/ /usr/dist/,请求 /my-app/js/app.js 会找 /usr/dist/js/app.js
      如果项目部署在子路径,用 alias 更稳妥,比如子路径部署时,server 配置改成:
      location /my-app/ {
        alias /usr/local/nginx/html/my-vue2-app/dist/;
        try_files $uri $uri/ /my-app/index.html; 
        # 注意 index.html 的路径要对应 alias 后的位置
      }

坑 3:跨域请求失败(生产环境)

开发时用 devServer.proxy 能解决跨域,但生产环境前端和后端域名不同,就会触发浏览器同源策略。

解决方法二选一

  1. 后端设置 CORS 头(推荐):让后端在响应头加 Access-Control-Allow-Origin: *(或指定前端域名)、Access-Control-Allow-Methods: GET,POST,... 等。

  2. Nginx 反向代理(前端请求走 Nginx 转发,避免跨域):
    比如前端请求 /api 开头的接口,Nginx 把 /api 转发到后端地址:

    location /api {
        proxy_pass https://backend-domain.com; # 后端真实地址
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        # 其他代理配置...
    }

    这样前端 Axios 的 baseURL 设为 '/api',请求就会被 Nginx 代理到后端,绕开跨域。

坑 4:部署后页面样式错乱、JS 报错(缓存问题)

现象:明明更新了代码,部署后还是旧样式/功能,强制刷新也没用。

原因:Nginx 或浏览器缓存了旧的静态资源。

解决组合拳

  1. 打包时让资源文件名带 hash:Vue CLI 默认开启,打包后文件是 app.xxx.jschunk-xxx.css,这样每次构建 hash 不同,强制浏览器重新请求。

  2. Nginx 配置缓存策略时,对带 hash 的资源设置长缓存,对 index.html 设置不缓存:

    # 对 index.html 禁用缓存(因为路由变化靠它)
    location = /index.html {
        add_header Cache-Control "no-cache, no-store, must-revalidate";
        add_header Pragma no-cache;
        add_header Expires 0;
    }
    # 对带 hash 的静态资源设置长缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico)(\?.*)?$ {
        expires 30d;
        add_header Cache-Control "public, max-age=2592000";
    }
  3. 强制刷新:用户端按 Ctrl+F5(强制清除缓存重新请求),或部署时加版本号参数(index.html?version=202401)。

坑 5:Nginx 启动失败或配置不生效

现象:执行 nginx -s reload 没反应,或访问时显示 Nginx 默认页面。

排查步骤

  1. 检查配置语法:执行 nginx -t,看是否报 configuration file /etc/nginx/nginx.conf test is successful,有错误就根据提示改。

  2. 检查端口占用:netstat -tunlp | grep 80(Linux),看 80 端口是否被其他程序占用,Apache。

  3. 检查文件路径:rootalias 配置的路径是否存在,文件权限是否给 Nginx 用户(Linux 下 Nginx 默认用户是 www-datanginx,要确保它能读 dist 目录)。

进阶:Nginx 性能优化+多环境部署技巧

搞定基础部署后,还能折腾这些进阶操作:

开启 Gzip 压缩,减少传输体积

Nginx 支持对静态资源(js、css、html)压缩后再发给浏览器,能省 50%+ 流量,配置如下:

http {
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    gzip_min_length 1k; # 小于 1k 不压缩
    gzip_comp_level 5; # 压缩级别 1-9,5 是平衡
    gzip_buffers 4 16k;
    gzip_http_version 1.1;
    gzip_vary on; # 告诉代理服务器缓存压缩和未压缩版本
}

多环境部署:测试、预发、生产

如果想一套 Nginx 同时部署多个环境(比如测试环境用 test.xxx.com,生产用 xxx.com),可以配置多个 server 块:

    listen 80;
    server_name test.xxx.com;
    root /usr/nginx/dist-test;
    # ...其他配置(try_files、缓存等)
}
# 生产环境
server {
    listen 80;
    server_name xxx.com;
    root /usr/nginx/dist-prod;
    # ...其他配置
}

打包时,通过 --mode 指定环境:

# 测试环境打包
vue-cli-service build --mode test 
# 生产环境打包
vue-cli-service build --mode production

然后把不同环境的 dist 包放到对应的 Nginx 目录即可。

HTTPS 配置:让站点更安全

现在主流站点都用 HTTPS,Nginx 配置步骤:

  1. 申请 SSL 证书(Let’s Encrypt 免费证书或付费证书),得到 cert.pemprivkey.pem 文件。

  2. 配置 Nginx 的 server 块支持 HTTPS:

    server {
     listen 443 ssl;
     server_name xxx.com;
     ssl_certificate /path/to/cert.pem; # 证书路径
     ssl_certificate_key /path/to/privkey.pem; # 私钥路径
     ssl_protocols TLSv1.2 TLSv1.3; # 安全协议
     ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5; # 加密套件
     # 强制 HTTP 跳转到 HTTPS
     location / {
         return 301 https://$host$request_uri;
     }
     # 其他配置(root、try_files 等)...
    }
  3. 重启 Nginx:nginx -s reload,然后访问 https://xxx.com 验证。

部署流程再梳理

最后把整个部署链路理清楚,避免遗漏步骤:

  1. 确认 Vue2 项目配置:

    • 路由模式(history 需后端/Nginx 配合)
    • publicPath 与部署路径一致
    • Axios 基础路径区分环境
  2. 打包项目:npm run build,得到 dist 目录。

  3. 上传 dist 到 Nginx 的对应目录(如 /usr/local/nginx/html/my-app/)。

  4. 配置 Nginx 的 server 块:

    • 正确设置 root/alias、try_files(history 模式)
    • 处理静态资源缓存、跨域、Gzip 等
  5. 测试验证:

    • 访问首页,点击路由跳转,刷新页面→检查是否 404
    • 打开控制台,检查资源加载、接口请求是否正常
    • 测试不同环境(如测试、生产)的访问逻辑

Vue2+Nginx 部署不难,核心是“前端路由和后端静态服务的配合”+“配置细节的严谨性”,碰到问题时,先看控制台报错(资源路径?接口跨域?),再对应 Nginx 配置和项目打包逻辑,基本都能定位,多试几次,部署就变成 routine 操作啦~

(如果还有特殊场景,Docker 里部署 Nginx+Vue2,或者结合 Jenkins 自动部署,评论区喊我,下次展开讲!)

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门