你正在 进阶版 · ⚡ 代码俱乐部 · ← 回到学院 · 进阶版主页 · 总入口

← 十二个项目

项目 04 · 真页面,自动部署

Vite + TypeScript + Tailwind。GitHub Actions 自动构建、自动部署。每次 push 都更新线上版本。

怎么算"成"?

有一个真上线的网址;每次 push 后线上自动更新;同事/同学打开后能直接用。

步骤 1 · 初始化项目

npm create vite@latest my-site -- --template vanilla-ts
cd my-site
npm install
npm run dev   # 本地预览

步骤 2 · 写真页面

不要 hello world。写一个你真要用的页面 —— 一个学习卡片应用、一个个人小工具、一个游戏的关卡查看器。具体到家人/同学会用的程度。

步骤 3 · 配自动部署

# .github/workflows/deploy.yml
name: Deploy
on: { push: { branches: [main] } }
permissions: { contents: read, pages: write, id-token: write }
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - run: npm ci && npm run build
      - uses: actions/upload-pages-artifact@v3
        with: { path: dist }
  deploy:
    needs: build
    runs-on: ubuntu-latest
    environment: github-pages
    steps:
      - uses: actions/deploy-pages@v4

步骤 4 · 启用 GitHub Pages

仓库 Settings → Pages → Source: GitHub Actions。等几分钟,你的网址就有了:https://yourname.github.io/my-site/

← 上一个下一个:接本地 AI →

工程测验 什么时候需要把 HTML 打包成 TypeScript?
你的网页项目从「一个 HTML + CSS + JS」变成了「很多页面,共享样式和组件」。下面哪个说法对?
解释:打包工具和 TypeScript 的价值不是「功能」,是「可维护性」。当你有多个文件相互依赖时,TypeScript 的类型检查能提前发现错误,Vite 的热更新能加快开发。
分步引导 把一个 HTML 项目迁移到 Vite + TypeScript 的 4 步
  1. 检查你现有的依赖。列出所有 import 的外部库(jQuery、React、Vue 等)和内部模块。
    看参考

    例:现有项目:`import './shared.css'`、`` —— Vite 能处理 CSS import,但对于全局脚本需要改造成 ES 模块。

  2. 创建 `index.html` 作为入口。把所有 ``。
    看参考

    例:原来是 ``,现在就一行:``。

  3. 写 `tsconfig.json` 和 `vite.config.js`。配置模块解析、输出目录、dev server 端口。
    看参考

    例:`vite.config.js` 里设置 `root: './'`, `build: { outDir: 'dist' }`,让输出到 dist 目录。

  4. 逐个文件从 JS 改成 TS。一个一个文件加入类型注解,直到整个项目能通过 `tsc --noEmit` 检查。
    看参考

    例:把 `function fetchData(url)` 改成 `function fetchData(url: string): Promise`。

动手 写一个 Fetch wrapper 加 retry 逻辑
任务:在 Vite + TypeScript 的项目里,写一个 `fetchWithRetry(url, options, maxRetries)` 函数。失败时自动重试,但要避免重试 4xx 错误。
参考实现

工程级参考答案(带完整注释):

// 生产级 Fetch wrapper
interface FetchOptions extends RequestInit {
  timeout?: number;
  retryableStatuses?: number[];
}

async function fetchWithRetry(
  url: string,
  options: FetchOptions = {},
  maxRetries: number = 3
): Promise {
  const { timeout = 5000, retryableStatuses = [408, 429, 500, 502, 503, 504], ...fetchOpts } = options;
  let lastError: Error | null = null;
  
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      // 添加超时控制
      const controller = new AbortController();
      const timeoutId = setTimeout(() => controller.abort(), timeout);
      
      const response = await fetch(url, {
        ...fetchOpts,
        signal: controller.signal,
      });
      
      clearTimeout(timeoutId);
      
      // 4xx 错误不重试
      if (response.status >= 400 && response.status < 500 && !retryableStatuses.includes(response.status)) {
        return response;
      }
      
      // 重试检查
      if (response.ok || !retryableStatuses.includes(response.status)) {
        return response;
      }
      
      throw new Error(`HTTP ${response.status}`);
    } catch (err) {
      lastError = err instanceof Error ? err : new Error(String(err));
      
      if (attempt < maxRetries) {
        const delay = Math.pow(2, attempt - 1) * 1000;
        console.warn(`Attempt ${attempt} failed, retrying in ${delay}ms...`);
        await new Promise(r => setTimeout(r, delay));
      }
    }
  }
  
  throw lastError || new Error(`Failed after ${maxRetries} attempts`);
}
动手 写一个 Vite 项目的初始化 checklist
任务:写一个给新手的 Vite 项目 checklist prompt。包括:(1) 项目结构(src/, dist/, public/);(2) 必须的配置文件;(3) TypeScript 的严格模式设置;(4) 开发和构建的常用命令。

在下面框里写你自己的 prompt(可以用中文):

→ 打开通义千问粘贴试 已复制 ✓
看参考 prompt

参考 prompt(这是一个模板,你可以改细节):

你是一个领域专家。请基于以下规则回答问题:

1. 只基于你的专业知识和常见做法回答,不编造。
2. 如果问题超出你的领域,明确说「这不在我的专业范围内」。
3. 给出的建议应该包括「为什么」和「什么时候不应该这样做」。
4. 对于有争议的做法,列出不同观点。

现在,开始回答用户的问题。