前端部署到服务器上怎么弄

文章导读
前端部署到服务器上,最小闭环只有三步:本地把源码构建成静态文件,把静态文件放进服务器上的一个目录,再让 Web 服务器(多数情况是 nginx)把这个目录按 HTTP 提供出去。卡住的时候先别急着改配置,先确认服务器上那个目录里到底有没有构建产物,这一步能排掉大半问题。
📋 目录
  1. A 前端部署到服务器上:先把能核对的事实摆清楚
  2. B 前端部署到服务器上最容易搞错的一点
  3. C 前端部署到服务器上:一个照着就能做完的做法
  4. D 前端部署到服务器上:怎么验证结果对不对
A A

前端部署到服务器上,最小闭环只有三步:本地把源码构建成静态文件,把静态文件放进服务器上的一个目录,再让 Web 服务器(多数情况是 nginx)把这个目录按 HTTP 提供出去。卡住的时候先别急着改配置,先确认服务器上那个目录里到底有没有构建产物,这一步能排掉大半问题。

判断顺序建议是:本地构建是否成功、产物是否真的传到了服务器、nginx 的 root 是否指向该目录、外部请求是否真的落到这个 server 块。四步里任何一步断掉,页面都会白屏或 404,但原因完全不同。首次上传建议不要带 --delete,确认目录内容对得上再开启,否则容易把服务器上原有的上传文件或旧配置一起删掉。

前端部署到服务器上:先把能核对的事实摆清楚

这里的对象是任意前端框架打包后产出的静态站点,产物就是 index.html 加上 css、js、图片等资源,服务器上不需要跑 Node 进程来渲染页面。前提条件有三条:能登录服务器并写入目标目录、Web 服务器已安装并处于运行状态、域名或 IP 已经能访问到这台机器。

下面这些都能当场看到结果,不依赖猜测:

  • 产物目录里有什么:ls -l /var/www/site,应看到 index.html 与 assets 之类的子目录。
  • nginx 实际生效的配置:nginx -T | grep -n 'root\|server_name',确认 root 指向的路径和前面一致。
  • 服务状态:systemctl status nginx,看 active 还是 failed。
  • 错误日志位置:多数发行版在 /var/log/nginx/error.log,用 tail -n 50 /var/log/nginx/error.log 看最近的报错。
  • 如果用的是面板,对应字段通常叫「网站根目录」「运行状态」「伪静态」,重点核对根目录填的是不是产物目录。

还有一个容易忽略的事实:产物目录名由框架配置决定,Vite 默认是 dist,Create React App 默认是 build,改动过配置的话要去 vite.config.* 里的 build.outDir 或 package.json 的 build 脚本里核对,不要凭印象。

前端部署到服务器上最容易搞错的一点

最常见的误解是把整个项目目录(含 src、node_modules、package.json)传到服务器,然后在服务器上跑 npm run dev 或 npm start,就认为部署完成了。开发服务器不是部署:它通常只监听本机地址、带热更新和源码映射,对外既不稳定也不合适长期使用。

判断分界很直接——请求最终是被 nginx 当作静态文件读取,还是被转发给某个 Node 端口。能区分这两种情况的检查动作是在服务器上执行:

前端部署到服务器上怎么弄
curl -I http://127.0.0.1/
curl -I http://127.0.0.1:5173/

第一条返回 200 并且在响应头里看到 Server: nginx,说明请求走的是静态文件;如果返回 502 或 504,说明 nginx 只是把请求转给了某个没起来的上游端口。第二条如果能通,说明你手上跑的是开发服务器,它和部署是两件事。再补一个更直观的动作:ls /var/www/site 里如果出现 src、node_modules,那就是把源码目录当成了站点根目录,浏览器请求 /src/main.js 当然拿不到想要的东西。

前端部署到服务器上:一个照着就能做完的做法

按下面五步走,每一步都写清了该看到什么。

第一步,本地构建。在项目根目录执行:

npm ci
npm run build
ls -l dist

该看到 dist/index.html 和 dist/assets/ 下一批带哈希的 js、css 文件。构建失败就先解决构建报错,不要往下走。

第二步,上传产物。只传 dist 里的内容,不传 dist 这一层目录本身:

前端部署到服务器上怎么弄
rsync -avz ./dist/ root@your-server:/var/www/site/

结尾的斜杠决定同步语义,./dist/ 表示同步目录内容。首次不加 --delete;确认服务器目录里没有需要保留的文件后,再加 --delete 保持产物干净。上传过程该看到逐条文件名列表和最后的传输统计。

第三步,写 nginx 配置。新建 /etc/nginx/conf.d/site.conf:

server {
    listen 80;
    server_name example.com;
    root /var/www/site;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }

    location /api/ {
        proxy_pass http://127.0.0.1:8080/;
    }
}

server_name 换成自己的域名或 IP,/api/ 这一段按后端实际地址改,没有后端就整段删掉。try_files 那行是给前端路由用的,缺了它刷新子路由会 404。

第四步,校验并重载:

前端部署到服务器上怎么弄
nginx -t
systemctl reload nginx

nginx -t 该看到 syntax is ok 和 test is successful 两行,任何一行报错都不要 reload。

第五步,确认读取权限。先查 nginx 以哪个用户运行:

ps -o user= -C nginx

然后用查到的用户名(Debian 系常见 www-data,部分镜像里是 nginx)执行:

chown -R www-data:www-data /var/www/site
find /var/www/site -type d -exec chmod 755 {} \;
find /var/www/site -type f -exec chmod 644 {} \;

前端部署到服务器上:怎么验证结果对不对

不要只看首页能不能打开,按下面几条逐个对:

  1. curl -I http://127.0.0.1/,正常结果是 HTTP 状态 200、Content-Type: text/html。返回 403 多半是权限或 index 缺失,返回 404 多半是 root 指错了目录。
  2. curl -s http://127.0.0.1/ | head -c 300,应该能看到 index.html 里的挂载节点,以及 script 标签引用的 assets 路径。
  3. 从第 2 步输出里取一个真实资源路径,执行 curl -I http://127.0.0.1/assets/那个文件名.js,正常返回 200 且 Content-Type 含 javascript。这一步能确认静态资源目录也通。
  4. 在浏览器里直接访问一个前端子路由地址并刷新,比如 /user/1,正常应该仍然返回页面而不是 404,说明 try_files 生效。
  5. tail -f /var/log/nginx/access.log,刷新页面时应该出现状态码 200 的请求行;如果出现大量 404 指向 /assets/...,说明产物没传全或路径前缀不对。

如果首页返回 200 但页面白屏,先按 F12 看 Network 里静态资源的状态码和 Console 的报错。产物部署在子路径(比如 /admin/)时,需要在构建配置里设置 base 或 publicPath,否则资源仍按根路径请求,就会整片 404。这类问题改配置重新构建即可,不要在 nginx 里反复加 rewrite 绕。