关于 web-app-builder
web-app-builder 是用于构建并部署云端静态 Web 应用的技能,涵盖多种前端框架和原生 HTML,并提供部署流程及可选的 Netlify Functions 支持。
主要功能
- 01React、Vue、Astro、Next.js、Svelte 和 HTML 构建指引
- 02通过上传与部署 API 发布静态站点
- 03配置 SPA 路由
- 04可选 Netlify Functions 与 Edge Functions
- 05查询部署状态和删除站点
适用场景
- 01部署基于框架的静态 Web 应用
- 02发布原生 HTML、CSS 和 JavaScript 站点
- 03为已部署站点添加无服务器 API 端点
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ rebyteai-template/ rebyte-skills --skill web-app-builder安装后在 Claude Code 中输入/web-app-builder确认已加载。
附带文件.gitignoreREADME.md
详细介绍
Web 应用构建器
构建并部署 Web 应用到云端,自动配置 SSL 和自定义子域名。
支持的框架
| 框架 | 构建命令 | 输出目录 | 备注 |
|---|---|---|---|
| React (Vite) | npm run build | dist/ | 单页应用(SPA),需要 _redirects |
| React (CRA) | npm run build | build/ | 单页应用(SPA),需要 _redirects |
| Vue (Vite) | npm run build | dist/ | 单页应用(SPA),需要 _redirects |
| Astro | npm run build | dist/ | 默认生成静态页面 |
| Next.js (static) | npm run build | out/ | 需要配置 output: 'export' |
| Vanilla HTML | 无 | . | 仅包含 HTML/CSS/JS 文件 |
| Svelte | npm run build | build/ | 单页应用(SPA),需要 _redirects |
无服务器后端支持
| 类型 | 位置 | 访问 URL |
|---|---|---|
| Netlify Functions | netlify/functions/ | /.netlify/functions/{name} |
| Edge Functions | netlify/edge-functions/ | 在 netlify.toml 中配置 |
应该做什么
- 部署前务必先构建 - 先运行框架的构建命令
- 在根目录包含
index.html- 这是必需的入口点 - 为单页应用添加
_redirects- React/Vue 应用需要此文件来支持客户端路由 - 使用相对路径 - 所有资源路径都应使用相对路径(
./assets/而不是/assets/) - 先在本地测试 - 部署前预览构建结果
- 保持构建产物精简 - 优化图片并压缩代码
不应该做什么
- 不要部署
node_modules/- 只部署构建输出 - 不要部署源文件 - 部署
dist/,而不是src/ - 不要硬编码 localhost URL - 使用相对路径或环境变量
- 不要包含
.env文件 - 使用 Netlify 环境变量存储密钥 - 不要跳过构建步骤 - 原始源代码无法正常运行
- 不要使用服务端渲染 - 仅支持静态导出(不支持 SSR)
如何构建
React (Vite)
# Install dependencies
npm install
# Build for production
npm run build
# Output: dist/
添加 _redirects 以支持单页应用路由:
echo "/* /index.html 200" > dist/_redirects
React (Create React App)
npm install
npm run build
# Output: build/
添加 _redirects:
echo "/* /index.html 200" > build/_redirects
Vue (Vite)
npm install
npm run build
# Output: dist/
添加 _redirects:
echo "/* /index.html 200" > dist/_redirects
Astro
npm install
npm run build
# Output: dist/
无需添加 _redirects - Astro 会生成静态 HTML 页面。
Next.js (静态导出)
首先,配置 next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export', // Required for static export
images: {
unoptimized: true // Required for static export
}
}
module.exports = nextConfig
然后构建:
npm install
npm run build
# Output: out/
原生 HTML/CSS/JS
无需构建。只需确保包含:
project/
├── index.html # Required
├── style.css
└── script.js
Svelte (SvelteKit)
配置 svelte.config.js 以生成静态页面:
import adapter from '@sveltejs/adapter-static';
export default {
kit: {
adapter: adapter({
pages: 'build',
assets: 'build',
fallback: 'index.html' // For SPA mode
})
}
};
然后构建:
npm install
npm run build
# Output: build/
如何部署
步骤 1:获取上传 URL
curl -X POST https://api.rebyte.ai/api/data/netlify/get-upload-url \
-H "Content-Type: application/json" \
-d '{"taskId": "my-app"}'
响应:
{
"deployId": "my-app-x7k2",
"uploadUrl": "https://storage.googleapis.com/...",
"expiresIn": 3600
}
保存 deployId 和 uploadUrl,以供后续步骤使用。
步骤 2:从构建输出创建 ZIP
# For Vite (React/Vue)
cd dist && zip -r ../site.zip . && cd ..
# For Create React App
cd build && zip -r ../site.zip . && cd ..
# For Next.js static
cd out && zip -r ../site.zip . && cd ..
# For Astro
cd dist && zip -r ../site.zip . && cd ..
步骤 3:上传 ZIP
curl -X PUT "${uploadUrl}" \
-H "Content-Type: application/zip" \
--data-binary @site.zip
步骤 4:部署
curl -X POST https://api.rebyte.ai/api/data/netlify/deploy \
-H "Content-Type: application/json" \
-d '{"deployId": "my-app-x7k2"}'
响应:
{
"deployId": "my-app-x7k2",
"url": "https://my-app-x7k2.rebyte.pro",
"status": "deployed"
}
你的网站现已上线! SSL 将在 1-2 分钟内激活。
完整的构建与部署脚本
#!/bin/bash
set -e
# Configuration
PROJECT_DIR="."
BUILD_CMD="npm run build"
BUILD_OUTPUT="dist"
TASK_ID="my-app-$(date +%s)"
API_URL="https://api.rebyte.ai/api/data/netlify"
# Step 1: Build
echo "Building project..."
cd "$PROJECT_DIR"
npm install
$BUILD_CMD
# Add SPA redirects if needed (for React/Vue)
echo "/* /index.html 200" > "$BUILD_OUTPUT/_redirects"
# Step 2: Get upload URL
echo "Getting upload URL..."
RESPONSE=$(curl -s -X POST "$API_URL/get-upload-url" \
-H "Content-Type: application/json" \
-d "{\"taskId\": \"$TASK_ID\"}")
DEPLOY_ID=$(echo $RESPONSE | jq -r '.deployId')
UPLOAD_URL=$(echo $RESPONSE | jq -r '.uploadUrl')
# Step 3: Create ZIP
echo "Creating ZIP..."
cd "$BUILD_OUTPUT"
zip -r /tmp/site.zip .
cd ..
# Step 4: Upload
echo "Uploading..."
curl -s -X PUT "$UPLOAD_URL" \
-H "Content-Type: application/zip" \
--data-binary @/tmp/site.zip
# Step 5: Deploy
echo "Deploying..."
RESULT=$(curl -s -X POST "$API_URL/deploy" \
-H "Content-Type: application/json" \
-d "{\"deployId\": \"$DEPLOY_ID\"}")
SITE_URL=$(echo $RESULT | jq -r '.url')
echo ""
echo "========================================="
echo "Deployed successfully!"
echo "URL: $SITE_URL"
echo "========================================="
完整的 Python 示例
import requests
import zipfile
import os
import subprocess
API_URL = "https://api.rebyte.ai/api/data/netlify"
def build_and_deploy(
project_dir: str,
build_cmd: str = "npm run build",
build_output: str = "dist",
task_id: str = None,
is_spa: bool = True
) -> str:
"""
Build and deploy a web app.
Args:
project_dir: Path to project root
build_cmd: Build command (e.g., "npm run build")
build_output: Build output directory (e.g., "dist", "build", "out")
task_id: Unique deployment ID (auto-generated if not provided)
is_spa: Whether to add SPA redirects (for React/Vue)
Returns:
Deployed site URL
"""
import time
if task_id is None:
task_id = f"app-{int(time.time())}"
# Step 1: Install dependencies
print("Installing dependencies...")
subprocess.run(["npm", "install"], cwd=project_dir, check=True)
# Step 2: Build
print(f"Building with: {build_cmd}")
subprocess.run(build_cmd.split(), cwd=project_dir, check=True)
build_path = os.path.join(project_dir, build_output)
# Step 3: Add SPA redirects if needed
if is_spa:
redirects_path = os.path.join(build_path, "_redirects")
with open(redirects_path, "w") as f:
f.write("/* /index.html 200\n")
print("Added _redirects for SPA routing")
# Step 4: Get upload URL
print("Getting upload URL...")
response = requests.post(
f"{API_URL}/get-upload-url",
json={"taskId": task_id}
)
response.raise_for_status()
data = response.json()
deploy_id = data["deployId"]
upload_url = data["uploadUrl"]
# Step 5: Create ZIP
print("Creating ZIP...")
zip_path = "/tmp/site.zip"
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
for root, dirs, files in os.walk(build_path):
for file in files:
file_path = os.path.join(root, file)
arcname = os.path.relpath(file_path, build_path)
zipf.write(file_path, arcname)
print(f"ZIP size: {os.path.getsize(zip_path)} bytes")
# Step 6: Upload
print("Uploading...")
with open(zip_path, 'rb') as f:
response = requests.put(
upload_url,
data=f,
headers={"Content-Type": "application/zip"}
)
response.raise_for_status()
# Step 7: Deploy
print("Deploying...")
response = requests.post(
f"{API_URL}/deploy",
json={"deployId": deploy_id}
)
response.raise_for_status()
result = response.json()
site_url = result["url"]
print(f"\nDeployed! URL: {site_url}")
return site_url
# Example usage for different frameworks
if __name__ == "__main__":
# React (Vite)
url = build_and_deploy(
project_dir="./my-react-app",
build_cmd="npm run build",
build_output="dist",
is_spa=True
)
# # Astro (not a SPA)
# url = build_and_deploy(
# project_dir="./my-astro-site",
# build_cmd="npm run build",
# build_output="dist",
# is_spa=False
# )
# # Next.js static export
# url = build_and_deploy(
# project_dir="./my-next-app",
# build_cmd="npm run build",
# build_output="out",
# is_spa=False
# )
添加无服务器函数
使用 Netlify Functions 创建后端 API 端点。
目录结构
project/
├── dist/ # Frontend build output
├── netlify/
│ └── functions/
│ └── api.js # Serverless function
└── netlify.toml # Configuration
函数示例
netlify/functions/api.js:
export default async (request, context) => {
const url = new URL(request.url);
const path = url.pathname.replace('/.netlify/functions/api', '');
// GET /api/hello
if (request.method === 'GET' && path === '/hello') {
return Response.json({ message: 'Hello World!' });
}
// POST /api/data
if (request.method === 'POST' && path === '/data') {
const body = await request.json();
return Response.json({ received: body });
}
return new Response('Not Found', { status: 404 });
};
export const config = {
path: "/api/*"
};
配置
netlify.toml:
[build]
publish = "dist"
functions = "netlify/functions"
[[redirects]]
from = "/api/*"
to = "/.netlify/functions/api/:splat"
status = 200
部署包含函数的应用
在 ZIP 中包含 netlify/ 文件夹:
# Build frontend
npm run build
# Create ZIP with both frontend and functions
zip -r site.zip dist/ netlify/ netlify.toml
访问 API:https://your-site.rebyte.pro/api/hello
单页应用路由配置
单页应用(React、Vue、Svelte)需要特殊配置,以支持客户端路由。
选项 1:_redirects 文件
在构建输出目录中创建 _redirects:
/* /index.html 200
选项 2:netlify.toml
在项目根目录中创建 netlify.toml:
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
API 参考
获取上传 URL
POST https://api.rebyte.ai/api/data/netlify/get-upload-url
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
taskId | string | 是 | 部署的唯一标识符 |
部署
POST https://api.rebyte.ai/api/data/netlify/deploy
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
deployId | string | 是 | 通过 get-upload-url 获取的部署 ID |
检查状态
POST https://api.rebyte.ai/api/data/netlify/status
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
deployId | string | 是 | 部署 ID |
删除站点
POST https://api.rebyte.ai/api/data/netlify/delete
| 参数 | 类型 | 必填 | 描述 |
|---|---|---|---|
deployId | string | 是 | 部署 ID |
故障排除
部署后出现“找不到页面”
- 确保 ZIP 根目录中有
index.html - 对于 SPA,请添加
_redirects文件
路由无法正常工作(刷新时出现 404)
- 添加
_redirects文件:/* /index.html 200
资源未加载
- 使用相对路径(
./assets/而非/assets/) - 检查浏览器控制台中的 404 错误
构建失败
- 先运行
npm install - 检查
package.json中的构建脚本是否正确 - 确保 Node.js 版本兼容
函数无法正常工作
- 函数必须放在
netlify/functions/中 - 在 ZIP 中包含
netlify.toml - 在管理 URL 中查看函数日志
限制
| 资源 | 限制 |
|---|---|
| ZIP 大小 | 100MB |
| 上传 URL 有效期 | 1 hour |
| 函数执行时间 | 10 seconds |
| 函数内存 | 1024 MB |
评论
支持 Markdown