部署
构建 Rspress 文档网站后,下一步是部署它以使用户能够访问。本章介绍流行平台的部署策略和最佳实践。
部署概述
部署什么?
运行 npm run build 后,您将拥有准备部署的静态文件:
doc_build/
├── index.html
├── guide/
│ └── *.html
├── api/
│ └── *.html
├── assets/
│ ├── chunks/
│ ├── css/
│ └── images/
└── _rspress/这些是纯静态文件,可以托管在任何地方。
部署选项
- 静态托管: Vercel, Netlify, GitHub Pages, Cloudflare Pages
- 传统托管: Apache, Nginx, AWS S3
- CDN: CloudFront, Fastly, Akamai
- 容器: Docker, Kubernetes
Vercel 部署
快速部署
使用一个命令部署到 Vercel:
bash
# 安装 Vercel CLI
npm install -g vercel
# 部署
vercel
# 按照提示配置和部署GitHub 集成
- 推送到 GitHub:
bash
git init
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/username/repo.git
git push -u origin main- 连接到 Vercel:
- 访问 vercel.com
- 点击"Import Project"
- 选择您的仓库
- 配置构建设置:
- 构建命令:
npm run build - 输出目录:
doc_build - 安装命令:
npm install
- 构建命令:
- 部署:
- Vercel 在推送时自动部署
- Pull Request 的预览部署
- 从主分支进行生产部署
Vercel 配置
创建 vercel.json:
json
{
"buildCommand": "npm run build",
"outputDirectory": "doc_build",
"devCommand": "npm run dev",
"installCommand": "npm install",
"framework": null,
"cleanUrls": true,
"trailingSlash": false,
"headers": [
{
"source": "/assets/(.*)",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=31536000, immutable"
}
]
}
]
}Netlify 部署
拖放
快速部署的最简单方法:
- 构建您的网站:
npm run build - 访问 netlify.com
- 将
doc_build文件夹拖到部署区域 - 网站上线!
Git 集成
推送到 Git 仓库(GitHub, GitLab, Bitbucket)
连接到 Netlify:
- 登录 Netlify
- 点击"New site from Git"
- 选择您的仓库
- 配置:
- 构建命令:
npm run build - 发布目录:
doc_build
- 构建命令:
- 部署:
- 推送时自动部署
- PR 的部署预览
- 回滚能力
Netlify 配置
创建 netlify.toml:
toml
[build]
command = "npm run build"
publish = "doc_build"
[build.environment]
NODE_VERSION = "18"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
[[headers]]
for = "/assets/*"
[headers.values]
Cache-Control = "public, max-age=31536000, immutable"
[[headers]]
for = "/*.html"
[headers.values]
Cache-Control = "public, max-age=0, must-revalidate"GitHub Pages
GitHub Actions 部署
创建 .github/workflows/deploy.yml:
yaml
name: 部署到 GitHub Pages
on:
push:
branches: [main]
# 设置 GITHUB_TOKEN 的权限
permissions:
contents: read
pages: write
id-token: write
# 允许一个并发部署
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Build
run: npm run build
env:
NODE_ENV: production
- name: Upload artifact
uses: actions/upload-pages-artifact@v2
with:
path: ./doc_build
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v2GitHub Pages 配置
如果部署到仓库路径,配置 base path:
typescript
// rspress.config.ts
export default defineConfig({
base: '/repository-name/', // 用于 username.github.io/repository-name
// base: '/', // 用于 username.github.io
});启用 GitHub Pages
- 转到仓库设置
- 导航到 Pages 部分
- 选择"GitHub Actions"作为源
- 推送到主分支以触发部署
Cloudflare Pages
Wrangler CLI
bash
# 安装 Wrangler
npm install -g wrangler
# 登录 Cloudflare
wrangler login
# 部署
wrangler pages publish doc_buildGit 集成
- 连接仓库:
- 登录 Cloudflare 仪表板
- 转到 Pages
- 点击"Create a project"
- 连接 GitHub/GitLab 仓库
- 构建设置:
构建命令: npm run build
构建输出目录: doc_build
根目录: /- 环境变量(如果需要):
NODE_VERSION=18AWS S3 + CloudFront
S3 存储桶设置
bash
# 安装 AWS CLI
npm install -g aws-cli
# 配置 AWS 凭证
aws configure
# 创建 S3 存储桶
aws s3 mb s3://my-docs-site
# 启用静态网站托管
aws s3 website s3://my-docs-site/ \
--index-document index.html \
--error-document 404.html
# 上传文件
npm run build
aws s3 sync doc_build/ s3://my-docs-site/ \
--delete \
--cache-control "public, max-age=31536000" \
--exclude "*.html" \
--exclude "sitemap.xml"
# 使用不同缓存上传 HTML
aws s3 sync doc_build/ s3://my-docs-site/ \
--delete \
--cache-control "public, max-age=0, must-revalidate" \
--exclude "*" \
--include "*.html" \
--include "sitemap.xml"Docker 部署
Dockerfile
dockerfile
# 构建阶段
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# 生产阶段
FROM nginx:alpine
COPY --from=builder /app/doc_build /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]Nginx 配置
nginx
# nginx.conf
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
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 /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# 处理客户端路由
location / {
try_files $uri $uri/ /index.html;
}
# 安全头
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
}构建和运行
bash
# 构建镜像
docker build -t my-docs .
# 运行容器
docker run -d -p 8080:80 my-docs
# 访问 http://localhost:8080自定义服务器部署
Node.js 服务器
javascript
// server.js
const express = require('express');
const path = require('path');
const app = express();
const PORT = process.env.PORT || 3000;
// 提供静态文件
app.use(express.static(path.join(__dirname, 'doc_build'), {
maxAge: '1y',
etag: true,
}));
// 处理客户端路由
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'doc_build', 'index.html'));
});
app.listen(PORT, () => {
console.log(`服务器运行在 http://localhost:${PORT}`);
});Apache 配置
apache
# .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>
# 缓存控制
<IfModule mod_headers.c>
<FilesMatch "\.(html|xml)$">
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
</FilesMatch>
<FilesMatch "\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2)$">
Header set Cache-Control "max-age=31536000, public, immutable"
</FilesMatch>
</IfModule>部署优化
构建优化
typescript
// rspress.config.ts
export default defineConfig({
builderConfig: {
output: {
minify: true,
cleanDistPath: true,
},
performance: {
chunkSplit: {
strategy: 'split-by-experience',
},
preload: true,
prefetch: true,
},
},
});压缩
启用 Gzip/Brotli 压缩:
bash
# 预压缩文件
npm install -g gzipper
# Gzip 压缩
gzipper compress ./doc_build
# Brotli 压缩
gzipper compress ./doc_build --brotli环境特定构建
多环境
json
// package.json
{
"scripts": {
"build": "rspress build",
"build:staging": "NODE_ENV=staging rspress build",
"build:production": "NODE_ENV=production rspress build"
}
}环境配置
typescript
// rspress.config.ts
const isProd = process.env.NODE_ENV === 'production';
export default defineConfig({
base: isProd ? '/' : '/staging/',
head: [
['meta', { name: 'robots', content: isProd ? 'index,follow' : 'noindex,nofollow' }],
],
});监控和分析
Google Analytics
typescript
export default defineConfig({
head: [
[
'script',
{
async: true,
src: 'https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID',
},
],
[
'script',
{},
`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'GA_MEASUREMENT_ID');
`,
],
],
});部署检查清单
部署前:
- [ ] 成功运行
npm run build - [ ] 使用
npm run preview测试 - [ ] 验证所有页面正确加载
- [ ] 在移动设备上检查响应式设计
- [ ] 测试所有内部链接
- [ ] 验证 HTML
- [ ] 检查 Lighthouse 分数
- [ ] 配置适当的缓存头
- [ ] 设置 HTTPS/SSL
- [ ] 配置自定义域名
- [ ] 设置监控/分析
- [ ] 创建备份策略
- [ ] 记录部署过程
故障排除
404 错误
- 客户端路由: 为 SPA 配置服务器
- Base path: 检查
base配置是否与部署路径匹配 - 大小写敏感: URL 在 Linux 服务器上区分大小写
构建失败
bash
# 清除缓存并重建
rm -rf node_modules/.rspress doc_build
npm install
npm run build加载缓慢
- 启用压缩(Gzip/Brotli)
- 为资源使用 CDN
- 优化图片
- 检查 bundle 大小
- 启用 HTTP/2
最佳实践
性能
- 启用 CDN
- 使用 HTTP/2
- 启用压缩
- 优化图片
- 设置适当的缓存头
- 最小化 JavaScript
- 使用懒加载
安全性
- 启用 HTTPS
- 设置安全头
- 验证用户输入
- 保持依赖更新
- 使用内容安全策略
可靠性
- 自动化部署
- 准备环境
- 回滚能力
- 健康检查
- 错误监控
- 备份策略
下一步
恭喜您完成 Rspress 教程!您现在具备以下知识:
- 创建和构建文档网站
- 配置导航和路由
- 使用 MDX 和 React 组件
- 处理静态资源
- 实施国际化
- 部署到各种平台
其他资源
快速部署
最快部署方式:
- Vercel:
vercel(GitHub 集成) - Netlify: 拖放
doc_build文件夹 - GitHub Pages: 在仓库设置中启用
生产检查清单
- ✅ 启用 HTTPS
- ✅ 配置自定义域名
- ✅ 设置分析
- ✅ 错误监控激活
- ✅ 配置备份
- ✅ CI/CD 管道工作