前端部署终极详细指南
目录
- 部署前的准备
- 构建生产版本详解
- 部署方案选择与对比
- 手动部署详细流程
- 自动化部署(CI/CD)完整配置
- 服务器配置与优化
- 域名与HTTPS配置
- 部署后监控与维护
- 常见问题解决方案
- 最佳实践总结
1. 部署前的准备
1.1 代码优化
- 代码压缩:
// 使用TerserPlugin进行JS压缩
const TerserPlugin = require('terser-webpack-plugin');module.exports = {
optimization: {
minimizer: [new TerserPlugin({
parallel: true,
terserOptions: {
compress: { drop_console: true }, // 生产环境移除console
},
})],
},
};
- CSS优化:
- 使用
cssnano
进行CSS压缩 - 提取CSS到单独文件:
mini-css-extract-plugin
- 自动添加浏览器前缀:
postcss
+autoprefixer
1.2 环境变量管理
# .env.production
REACT_APP_API_BASE_URL=https://api.production.com
PUBLIC_URL=https://my-app.com
GA_TRACKING_ID=UA-XXXXX-X
1.3 性能审计
使用Lighthouse进行性能评估:
npm install -g lighthouse
lighthouse https://your-app.com --view
1.4 安全审计
- 检查依赖漏洞:
npm audit
- 使用Snyk扫描:
npx snyk test
- 检查敏感信息泄露:
git secrets --scan
2. 构建生产版本详解
2.1 构建命令分析
# React项目 (Create React App)
npm run build
# 实际执行的命令: react-scripts build# Vue CLI项目
npm run build
# 实际执行的命令: vue-cli-service build# Angular项目
ng build --prod
2.2 构建输出分析
典型构建输出结构:
dist/
├── index.html
├── static/
│├── css/
││├── main.abcd1234.css
││└── main.abcd1234.css.map
│├── js/
││├── main.efgh5678.js
││├── main.efgh5678.js.map
││├── runtime.ijk9012.js
││└── polyfills.mno3456.js
│└── media/
│└── logo.123abc.png
└── asset-manifest.json
2.3 高级构建配置
// vue.config.js
module.exports = {
productionSourceMap: false, // 关闭source map
filenameHashing: true, // 开启文件名哈希
chainWebpack: config => {
// 分割代码块
config.optimization.splitChunks({
chunks: 'all',
maxInitialRequests: Infinity,
minSize: 0,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
return `npm.${packageName.replace('@', '')}`;
}
}
}
});// 预加载关键资源
config.plugin('preload').tap(options => {
options[0].include = 'all-chunks';
return options;
});
}
};
3. 部署方案选择与对比
3.1 部署方案对比表
方案 | 适用场景 | 优点 | 缺点 | 典型成本 |
---|---|---|---|---|
静态托管平台 (Vercel/Netlify) | 中小项目 SPA应用 | 自动HTTPS 全球CDN 即时部署 | 高级功能收费 定制化有限 | 免费-$20/月 |
云存储+CDN (AWS S3+CloudFront) | 企业级应用 高流量网站 | 高度可定制 全球加速 精细控制 | 配置复杂 学习曲线陡峭 | $10-$500+/月 |
传统服务器 (Nginx/Apache) | 私有化部署 混合应用 | 完全控制 自定义配置 | 维护成本高 需手动扩展 | $5-$100+/月 |
容器化部署 (Docker/K8s) | 微服务架构 CI/CD流水线 | 环境一致 易于扩展 | 复杂度高 运维要求高 | $20-$1000+/月 |
Serverless (AWS Lambda) | 事件驱动应用 API网关 | 按使用付费 自动扩展 | 冷启动问题 调试困难 | $0-$100+/月 |
3.2 方案选择决策树
项目规模?
├── 小型/个人项目 → 静态托管平台
├── 中型项目 → 云存储+CDN
├── 大型/企业级 →
│├── 需要完全控制 → 容器化部署
│└── 需要自动扩展 → Serverless
└── 私有化部署需求 → 传统服务器
4. 手动部署详细流程
4.1 上传到AWS S3完整流程
- 创建S3存储桶
- 命名规范:
my-app-production
- 区域选择: 靠近用户的位置 (如
us-east-1
) - 禁用"阻止所有公开访问"
- 配置存储桶策略
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-app-production/*"
}
]
}
- 启用静态网站托管
- 属性 → 静态网站托管 → 启用
- 索引文档:
index.html
- 错误文档:
index.html
(SPA应用)
- 上传文件
# 安装AWS CLI
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install# 配置凭证
aws configure
# 输入Access Key ID和Secret Access Key# 同步构建目录到S3
aws s3 sync ./dist s3://my-app-production \
--delete \
--cache-control "max-age=31536000" \
--exclude "index.html" \
--exclude "asset-manifest.json"# 单独上传HTML文件(禁用缓存)
aws s3 cp ./dist/index.html s3://my-app-production \
--cache-control "no-cache, no-store, must-revalidate"
4.2 Nginx服务器部署
- 服务器准备
# 更新系统
sudo apt update && sudo apt upgrade -y# 安装Nginx
sudo apt install nginx -y# 创建应用目录
sudo mkdir -p /var/www/my-app
sudo chown -R $USER:$USER /var/www/my-app
sudo chmod -R 755 /var/www/my-app
- 上传文件
# 本地压缩构建文件
tar -czvf build.tar.gz -C ./dist .# 上传到服务器
scp build.tar.gz user@server_ip:/tmp# 在服务器上解压
ssh user@server_ip
sudo tar -xzvf /tmp/build.tar.gz -C /var/www/my-app
- Nginx配置
# /etc/nginx/sites-available/my-app
server {
listen 80;
listen [::]:80;server_name my-app.com www.my-app.com;
root /var/www/my-app;
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;
gzip_min_length 1000;
gzip_proxied any;# 缓存设置
location ~* \.(?:css|js|jpg|jpeg|gif|png|ico|svg|woff2)$ {
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
access_log off;
}# SPA路由处理
location / {
try_files $uri $uri/ /index.html;
add_header Cache-Control "no-cache, no-store, must-revalidate";
}# 禁止访问.git目录
location ~ /\.git {
deny all;
return 403;
}# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://www.google-analytics.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://www.google-analytics.com; font-src 'self'; connect-src 'self' https://api.my-app.com;" always;
}
- 启用配置
sudo ln -s /etc/nginx/sites-available/my-app /etc/nginx/sites-enabled/
sudo nginx -t # 测试配置
sudo systemctl reload nginx
5. 自动化部署(CI/CD)完整配置
5.1 GitHub Actions部署到Vercel
# .github/workflows/deploy.yml
name: Deploy to Productionon:
push:
branches: [ main ]
pull_request:
branches: [ main ]jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'- name: Install dependencies
run: npm ci- name: Build project
run: npm run build
env:
REACT_APP_API_BASE_URL: ${{ secrets.API_BASE_URL }}
REACT_APP_GA_ID: ${{ secrets.GA_TRACKING_ID }}- name: Run tests
run: npm test- name: Deploy to Vercel
uses: amondnet/vercel-action@v3
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
working-directory: './'
vercel-args: '--prod'
if: github.ref == 'refs/heads/main'- name: Post-Deploy Slack Notification
uses: slackapi/slack-github-action@v1.25.0
with:
channel-id: 'C12345678'
slack-message: 'Production deployment successful: ${{ github.sha }}'
env:
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
5.2 GitLab CI/CD部署到AWS S3
# .gitlab-ci.yml
image: node:20stages:
- test
- build
- deploycache:
paths:
- node_modules/variables:
AWS_DEFAULT_REGION: us-east-1
S3_BUCKET: my-app-production
BUILD_DIR: distbefore_script:
- npm citest:
stage: test
script:
- npm run test:cibuild:
stage: build
script:
- npm run build
- echo "Build completed at $(date)" > build-info.txt
artifacts:
paths:
- $BUILD_DIR
- build-info.txt
expire_in: 1 week
only:
- maindeploy:
stage: deploy
dependencies:
- build
script:
- apt-get update -yq
- apt-get install -y python3-pip
- pip3 install awscli --upgrade
- aws s3 sync $BUILD_DIR s3://$S3_BUCKET --delete
- aws s3 cp $BUILD_DIR/index.html s3://$S3_BUCKET --cache-control "no-cache"
- aws cloudfront create-invalidation --distribution-id $CF_DISTRIBUTION_ID --paths "/*"
environment:
name: production
url: https://my-app.com
only:
- main
6. 服务器配置与优化
6.1 高级Nginx配置
# 连接优化
events {
worker_connections 1024;
multi_accept on;
use epoll;
}http {
# 性能优化
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 1000;
types_hash_max_size 2048;
server_tokens off;# MIME类型
include /etc/nginx/mime.types;
default_type application/octet-stream;# SSL优化
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_buffer_size 4k;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1.2 TLSv1.3;# 日志格式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';access_log /var/log/nginx/access.log main;
error_log /var/log/nginx/error.log warn;# Gzip压缩
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_min_length 256;
gzip_buffers 16 8k;# Brotli压缩(需要额外模块)
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;# 包含站点配置
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
6.2 安全加固
- 防火墙配置
sudo ufw allow ssh
sudo ufw allow http
sudo ufw allow https
sudo ufw enable
- 防止暴力破解
# 安装fail2ban
sudo apt install fail2ban -y# 配置Nginx防护
sudo nano /etc/fail2ban/jail.d/nginx.conf
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 3
findtime = 3600
bantime = 86400
- 禁用不安全的协议
# 编辑/etc/ssh/sshd_config
Protocol 2
PermitRootLogin no
PasswordAuthentication no
AllowUsers deploy-user
7. 域名与HTTPS配置
7.1 Let’s Encrypt证书申请
# 安装Certbot
sudo apt install certbot python3-certbot-nginx -y# 获取证书
sudo certbot --nginx -d my-app.com -d www.my-app.com# 自动续期测试
sudo certbot renew --dry-run# 设置自动续期cron任务
sudo crontab -e
# 添加行: 0 12 * * * /usr/bin/certbot renew --quiet
7.2 DNS配置最佳实践
- 主域名记录
my-app.com.A300203.0.113.1
- WWW别名
www.my-app.com. CNAME 300my-app.com.
- SPF记录
my-app.com. TXT "v=spf1 include:_spf.google.com ~all"
- DMARC记录
_dmarc.my-app.com. TXT "v=DMARC1; p=quarantine; pct=100; rua=mailto:admin@my-app.com"
- DNSSEC启用
在域名注册商处启用DNSSEC保护
7.3 HTTP到HTTPS重定向
server {
listen 80;
listen [::]:80;
server_name my-app.com www.my-app.com;# 301永久重定向到HTTPS
return 301 https://$host$request_uri;
}server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name my-app.com www.my-app.com;# SSL证书路径
ssl_certificate /etc/letsencrypt/live/my-app.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my-app.com/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/my-app.com/chain.pem;# 其余配置...
}
8. 部署后监控与维护
8.1 监控工具栈
工具类型 | 推荐工具 | 用途 |
---|---|---|
应用性能 | New Relic, AppDynamics | 前端性能监控 |
错误追踪 | Sentry, Rollbar | JS错误捕获 |
日志管理 | ELK Stack, Papertrail | 服务器日志分析 |
实时监控 | Prometheus + Grafana | 资源使用监控 |
安全扫描 | Nessus, Qualys | 漏洞扫描 |
Uptime监控 | UptimeRobot, Pingdom | 可用性监控 |
8.2 维护计划
- 每日检查
- 服务器负载:
htop
,nmon
- 错误日志:
tail -f /var/log/nginx/error.log
- 应用健康检查:
curl -I https://my-app.com/health
- 每周任务
- 安全更新:
sudo apt update && sudo apt upgrade
- 备份验证:检查备份完整性
- 磁盘空间:
df -h
,du -sh /*
- 每月审计
- 安全扫描:
nmap -sV -O localhost
- 性能测试:
k6 run script.js
- 证书有效期:
certbot certificates
- 季度演练
- 灾难恢复演练
- 负载测试
- 安全渗透测试
9. 常见问题解决方案
9.1 路由404问题
问题描述:直接访问非根路径(如/dashboard
)返回404
解决方案:
location / {
try_files $uri $uri/ /index.html;
}
9.2 缓存问题
问题描述:用户看到旧版本页面
解决方案:
- 文件名添加内容哈希:
filename: '[name].[contenthash].js'
- 设置正确缓存头:
# 静态资源长期缓存
location ~* \.(?:css|js|jpg|jpeg|gif|png|ico|svg|woff2)$ {
expires 1y;
add_header Cache-Control "public, max-age=31536000, immutable";
}# HTML文件禁用缓存
location / {
add_header Cache-Control "no-cache, no-store, must-revalidate";
}
- 添加版本查询参数:
<script src="/app.js?v=1.2.3"></script>
9.3 HTTPS混合内容
问题描述:页面包含HTTP资源导致不安全警告
解决方案:
- 使用协议相对URL:
//example.com/image.jpg
- 添加CSP头:
add_header Content-Security-Policy "upgrade-insecure-requests;";
- 检查并修复所有HTTP资源
9.4 CORS问题
问题描述:跨域请求被阻止
解决方案:
- 后端配置正确CORS头:
location /api/ {
add_header 'Access-Control-Allow-Origin' 'https://my-app.com';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,Content-Type,Authorization';
add_header 'Access-Control-Allow-Credentials' 'true';
}
- 开发环境使用代理:
// vue.config.js
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://backend:3000',
changeOrigin: true
}
}
}
}
10. 最佳实践总结
- 自动化一切:从构建到部署全流程自动化
- 基础设施即代码:使用Terraform或CloudFormation管理基础设施
- 不可变部署:每次部署创建全新环境,而非修改现有环境
- 蓝绿部署:通过负载均衡器切换流量,实现零停机部署
- 渐进式Web应用(PWA):添加Service Worker实现离线访问
- 全球CDN加速:使用Cloudflare或AWS CloudFront分发静态资源
- 安全第一:定期进行安全扫描和渗透测试
- 监控可视化:建立完整的监控仪表盘
- 成本优化:使用预留实例和自动缩放控制成本
- 文档化:维护详细的部署手册和应急预案