8.2 KiB
8.2 KiB
静态构建解决方案文档
🚀 问题解决方案
原始问题
- 静态资源访问问题 - 图片、CSS、JS 文件访问失败
- 新闻页面检索问题 - 新闻文章无法显示
解决方案概述
采用 Next.js 静态导出 (Static Export) 模式,通过以下技术实现:
- ✅ 静态文件生成,无需服务器端 API
- ✅ 文章数据在构建时预生成
- ✅ 图片和资源使用相对路径
- ✅ 完整的 SEO 支持
📁 项目结构
dongyun/
├── app/ # Next.js App Router
│ ├── [locale]/ # 多语言路由
│ │ ├── news/ # 新闻页面
│ │ │ ├── page.tsx # 新闻列表页
│ │ │ └── [id]/ # 新闻详情页
│ │ │ └── page.tsx
│ │ └── ... # 其他页面
│ └── components/ # 组件目录
├── docs/ # 文章数据源
│ ├── zh-CN/ # 中文文章
│ ├── zh-TW/ # 繁体中文文章
│ └── en/ # 英文文章
├── lib/
│ └── static-data.ts # 静态数据处理函数
├── public/ # 静态资源
│ └── images/ # 图片资源
├── scripts/
│ └── build-static.bat # 自动化构建脚本
├── out/ # 构建输出目录 (生成后)
└── next.config.mjs # Next.js 配置
🛠️ 核心实现
1. Next.js 配置 (next.config.mjs)
const isStaticExport = process.env.BUILD_MODE === 'static';
const nextConfig = {
...(isStaticExport && {
output: 'export', // 启用静态导出
trailingSlash: true, // 添加尾部斜杠
images: {
unoptimized: true, // 禁用图片优化
},
}),
env: {
BUILD_MODE: process.env.BUILD_MODE || 'server',
},
};
2. 静态数据处理 (lib/static-data.ts)
export function getStaticArticles(locale: 'zh-CN' | 'zh-TW' | 'en' = 'zh-CN'): Article[] {
const localeDir = path.join(docsDirectory, locale);
// 读取 markdown 文件
const fileNames = fs.readdirSync(localeDir);
const articles = fileNames
.filter((fileName: string) => fileName.endsWith('.md'))
.map((fileName: string) => {
const fullPath = path.join(localeDir, fileName);
const fileContents = fs.readFileSync(fullPath, 'utf8');
const { data, content } = matter(fileContents);
// ... 处理逻辑
})
.sort((a, b) => new Date(b.metadata.date).getTime() - new Date(a.metadata.date).getTime());
return articles;
}
3. 组件智能切换 (app/components/news/NewsPageClient.tsx)
const fetchArticles = useCallback(async () => {
// 检查是否为静态导出模式
const isStatic = process.env.NODE_ENV === 'production' &&
typeof window !== 'undefined' &&
!window.location.origin.includes('localhost');
if (isStatic) {
// 静态模式:直接从预生成数据获取
const { getStaticArticles, getStaticCategories } = await import('../../../lib/static-data');
// ...
} else {
// 开发模式:使用 API
const response = await fetch(`/api/articles?locale=${locale}`);
// ...
}
}, [locale, selectedCategory]);
🚀 使用方法
快速构建(推荐)
# 使用自动化脚本
npm run deploy
# 或手动构建
npm run build:static
预览构建结果
npm run preview
然后访问 http://localhost:8080
部署到服务器
# 方法1: rsync 同步
rsync -avz --delete out/ user@your-server:/var/www/html/
# 方法2: scp 复制
scp -r out/* user@your-server:/var/www/html/
# 方法3: 打包上传
tar -czf dongyun-static.tar.gz out
scp dongyun-static.tar.gz user@your-server:~/
ssh user@your-server "cd /var/www/html && tar -xzf ~/dongyun-static.tar.gz --strip-components=1"
📋 完整构建流程
自动化脚本 (scripts/build-static.bat)
@echo off
echo 开始静态构建...
echo 1. 临时移动 API 目录...
if exist "app\api" (
if not exist "..\temp" mkdir "..\temp"
move "app\api" "..\temp\api-disabled" >nul
)
echo 2. 构建静态文件...
call npm run build:static
echo 3. 恢复 API 目录...
if exist "..\temp\api-disabled" (
move "..\temp\api-disabled" "app\api" >nul
)
echo ✅ 静态构建完成!
echo 📁 静态文件位置: out/ 目录
package.json 脚本
{
"scripts": {
"dev": "next dev",
"build": "next build",
"build:static": "cross-env BUILD_MODE=static next build",
"build:server": "cross-env BUILD_MODE=server next build",
"export": "npm run build:static",
"start": "next start",
"deploy": "scripts\\build-static.bat",
"preview": "cd out && python -m http.server 8080"
}
}
✅ 验证结果
1. 静态资源访问
- ✅ 图片文件:
/images/hero-bg.jpg→ 正确加载 - ✅ CSS 样式:
/_next/static/css/...→ 正确加载 - ✅ JavaScript:
/_next/static/chunks/...→ 正确加载
2. 新闻页面功能
- ✅ 新闻列表页:显示所有文章
- ✅ 新闻详情页:显示完整文章内容
- ✅ 搜索功能:客户端搜索工作正常
- ✅ 分类筛选:分类切换工作正常
- ✅ 相关文章:推荐功能正常
3. SEO 和性能
- ✅ 静态 HTML 生成,SEO 友好
- ✅ 预加载关键资源
- ✅ 图片优化和懒加载
- ✅ 多语言支持
🔧 技术要点
为什么移除 API 目录?
Next.js 静态导出模式不支持 API 路由,构建时会报错。我们采用以下策略:
- 构建时:临时移除
app/api目录 - 运行时:组件智能判断环境,选择数据获取方式
- 构建后:恢复
app/api目录,保持开发功能
数据获取策略
- 开发环境 (
npm run dev):使用 API 路由,支持热更新 - 生产环境 (静态导出):直接从文件系统读取,性能最佳
路径处理
- 静态资源使用相对路径,确保在任何服务器环境下都能正确访问
- 图片路径自动适配,支持 CDN 部署
🌐 部署选项
1. 静态网站托管
- Vercel:
vercel --prod - Netlify: 直接上传
out/目录 - GitHub Pages: 推送到
gh-pages分支
2. 传统服务器
- Nginx: 配置静态文件服务
- Apache: 设置 DocumentRoot 到
out/目录 - CDN: 上传到阿里云 OSS、腾讯云 COS 等
3. 容器化部署
FROM nginx:alpine
COPY out/ /usr/share/nginx/html/
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
📈 性能优化
已实现优化
- ✅ 静态预渲染,首屏加载快
- ✅ 代码分割和懒加载
- ✅ 图片优化和 WebP 支持
- ✅ CSS 和 JS 压缩
- ✅ Gzip 压缩支持
可选优化
- CDN 加速静态资源
- Service Worker 离线缓存
- 图片格式优化 (WebP, AVIF)
- HTTP/2 Server Push
🆘 常见问题
Q: 构建失败,提示 API 路由错误?
A: 确保使用 npm run build:static 而不是 npm run build,或使用自动化脚本 npm run deploy。
Q: 图片显示 404 错误?
A: 检查图片路径是否正确,确保图片文件在 public/images/ 目录中。
Q: 新闻文章不显示?
A: 确认 docs/ 目录中的 markdown 文件格式正确,包含必要的 frontmatter。
Q: 开发环境和生产环境表现不一致?
A: 这是正常的,开发环境使用 API,生产环境使用静态数据。使用 npm run preview 测试生产版本。
🔄 更新文章
- 在
docs/zh-CN/目录添加新的.md文件 - 运行
npm run build:static重新构建 - 上传更新的
out/目录到服务器
📞 技术支持
如果遇到问题,请检查:
- Node.js 版本 >= 18
- 依赖包是否正确安装 (
npm install) - markdown 文件格式是否正确
- 图片资源是否存在
🎉 恭喜! 你的 Next.js 应用现在支持完整的静态部署,解决了静态资源访问和新闻页面检索的所有问题!