Skip to content

Latest commit

 

History

History
387 lines (275 loc) · 11.5 KB

File metadata and controls

387 lines (275 loc) · 11.5 KB

贡献指北

开始 quick 'n dirty

  1. 一定准备好一个包管理器, in case you dont have one

    • windows: check out scoop
    • ubuntu: you got apt
    • archlinux: i use yay, but paru may be better
  2. 安装 node/npm + pnpm

    • 推荐直接运行仓库脚本,一次性补齐 nodenpm 和项目所需主版本的 pnpm:
    ./scripts/install-pnpm.sh
    • Windows PowerShell:
    .\scripts\install-pnpm.ps1
    • 如果系统里还没有 node / npm,脚本会先尝试通过系统包管理器自动安装
    • pnpm 会优先通过 corepack 下载并启用
    • 如果你的环境没有可用的 corepack,会回退到 npm install -g
    • 也可以手动指定版本,例如:
    PNPM_VERSION=pnpm@10 ./scripts/install-pnpm.sh
  3. 安装依赖

    pnpm install
  4. 开造!

    • 调试

      pnpm dev
    • 构建

      pnpm build
    • 本地预览构建结果

      pnpm preview
    • 可选格式化

      pnpm prettier -w .
  5. feel free to push,但至少先确认你改的页面能正常打开

Astro quick 'n dirty

  1. component usage

    1. import

      .astro 文件最上面的 frontmatter 里 import 其他组件,然后像 HTML 标签一样使用,例如引入 Card 之后写 <Card />

      ---
      import Card from "@/components/Card.astro";
      ---
      
      <Card title="Example">hello</Card>
    2. props

      组件参数和 React 那套意思差不多,父组件传,子组件在 Astro.props 里取;适合传标题、链接、状态、class 之类结构信息

      --- src/components/Example.astro
      const { title } = Astro.props;
      ---
      
      <h2>{title}</h2>
      --- src/contents/index.astro
      import Example from "@/components/Example.astro";
      ---
      
      <Example title="YatCC AI" />
    3. slot

      slot 用来把一整段子内容塞进组件里,适合做壳子组件;如果一个组件主要负责“布局容器”而不是“具体文案”,优先考虑 slot

      --- src/components/Shell.astro
      ---
      
      <section>
        <slot />
      </section>
      --- src/contents/index.astro
      import Shell from "@/components/Shell.astro";
      ---
      
      <Shell>
        <h1>Hello</h1>
        <p>Some content</p>
      </Shell>
  2. asset import

    图片、svg 之类资源一般从 src/assetspublic/ 引入;在 Astro 里可以像模块一样 import img from "...png" 再传给组件

    ---
    import logo from "@/assets/yatcc-icon.png";
    ---
    
    <img src={logo.src} width={logo.width} height={logo.height} alt="YatCC" />
  3. page content 尽量写在 src/contents 里,不要把具体文案塞进通用组件

    简单说就是:components 负责“长什么样”,contents 负责“写什么内容”;页面文案、卡片文字、section 标题这些都尽量放在 contents

    --- src/components/Hero.astro
    const { title, subtitle } = Astro.props;
    ---
    
    <header>
      <h1>{title}</h1>
      <p>{subtitle}</p>
    </header>
    --- src/contents/index.astro
    import Hero from "@/components/Hero.astro";
    import { getLangFromUrl } from "@/i18n/utils";
    
    const lang = getLangFromUrl(Astro.url);
    const t = <T,>(value: { zh: T; en: T }) => value[lang];
    ---
    
    <Hero
      title="YatCC AI"
      subtitle={t({
        zh: "中文介绍",
        en: "English introduction",
      })}
    />

项目结构

  1. 组件 src/components

    1. 全局布局 BaseLayout

      每一个路由页的最外层一般都会经过它,负责默认排版、主题和全局结构

    2. 单页壳子 / 页面骨架

      1. HomePageShell

        首页内容壳子,只负责整体结构和 slot,不负责具体文案

      2. TeachingPracticePageShell

        教学实践页内容壳子,只负责整体结构和 slot,不负责具体文案

    3. 页面片段组件

      1. HomeHero
      2. HomeFeatureSection
      3. TeachingHero
      4. TeachingOverview
      5. TeachingShowcase
    4. 页面布局组件

      1. FixPage + FixPageContainer

        固定高度页

      2. SnapPage + SnapContainer

        吸附式页面布局

      3. FeatureDisplayPage + FeatureDisplayPageFeature

        功能展示页及其中的 feature 卡片

    5. 基础 UI

      1. DarkLightButton

        随主题明暗变化的黑/白按钮

      2. Button

        主题色按钮

      3. OutlinedButton

        描边按钮

      4. ButtonGroup

        按钮组容器

      5. Card + CardContainer

        卡片及卡片容器

      6. Badge

        小标签

    6. 导航 / 链接

      1. Link

      2. NavDropdown

      3. Topbar

      4. YatccTopbar

        YatCC 默认导航栏

    7. 主题 / 装饰 / 其他

      1. ThemeManager

      2. ThemeToggleButton

      3. DragonParticles

        llvm 龙样粒子效果,基于 three.js,一般做背景

      4. HomeTitle

      5. Footer

      6. IntroductionPage

      7. ChatPannel

    8. 原则

      • components 尽量保持无具体内容耦合
      • 优先用 propsslot、shell/component 组合内容
      • 如果一个组件里开始堆很多具体文案,通常应该拆去 src/contents
  2. 内容 src/contents

    1. 这里放“有具体页面内容”的 Astro 文件,而不是通用组件

    2. 文件名尽量和页面 slug 对应

    3. 页面文案 i18n 采用 inline 形式,靠近实际渲染位置,例如:

      const t = <T,>(value: { zh: T; en: T }) => value[lang];
      <h1>{t({ zh: "中文标题", en: "English Title" })}</h1>
    4. 不要再新建集中式 page-content dictionary,除非真的有明确复用需求

博客系统 quick 'n dirty'

  1. 文章目录

    • 所有博客文章都放在 src/contents/blog/
    • 当前博客系统直接扫描这个目录下的 .md 文件,不走 Astro content collection
    • 因此不要再新建 src/content/ 之类容易混淆的内容目录
  2. 一篇文章最少需要这些 frontmatter

    ---
    title: "Demo/Test:首页时间线节点联调"
    summary: 用来测试首页 timeline 的显式 demo 文章,确认节点、跳转和时间排序都正常。
    date: 2026-05-19
    lang: zh
    category: Demo
    ---

    字段说明:

    • title: 文章标题
    • summary: 摘要,会展示在博客列表和部分首页上下文里
    • date: 发布时间,决定排序
    • lang: 语言,只能是 zhen
    • category: 可选,分类标签
    • pinned: 可选,true 时会优先排序
    • draft: 可选,true 时不会出现在页面里
  3. 路由约定

    • 博客列表页:
      • /zh/blog
      • /en/blog
    • 博客详情页:
      • /zh/blog/<slug>
      • /en/blog/<slug>
    • 无语言前缀的 /blog 会重定向到默认语言 /zh/blog
  4. 首页时间线

    • 首页 timeline/news 区域会自动读取博客目录中的最新文章
    • 宽屏下只显示当前布局能容纳的最新几篇
    • 窄屏下切换为竖向时间线
    • 新增文章后不需要手动改首页内容
  5. 新增文章 quick 'n dirty

    1. src/contents/blog/ 新建一个 markdown 文件

    2. 写好 frontmatter 和正文

    3. 如果做双语内容,分别新建 *-zh.md*-en.md

    4. 运行:

      pnpm build

      pnpm dev
    5. 确认:

      • /zh/blog/en/blog 能看到文章
      • 首页 timeline 能看到对应节点
      • 点击节点能跳到详情页
  6. 相关实现文件

  7. 路由 src/pages

    1. 无语言前缀路由入口 [[...slug].astro](<src/pages/[...slug].astro>)

      负责把 //teaching-practice 这类路径重定向到默认语言

    2. 带语言前缀路由入口 [[lang]/[...slug].astro](<src/pages/[lang]/[...slug].astro>)

      负责把 /zh/.../en/... 分发到对应 contents 页面

    3. 目前内容页需要在这个文件里注册 slug,新增页面时记得一起改

    4. 现有中文文档页 src/pages/zh/about.md

    5. 博客页已拆到独立路由目录 src/pages/[lang]/blog/

      • 博客文章不需要再在 [[lang]/[...slug].astro](<src/pages/[lang]/[...slug].astro>) 里手动注册
  8. i18n src/i18n

    1. ui.ts

      放共享导航、按钮等全局短文本

    2. utils.ts

      getLangFromUrluseTranslationsuseTranslatedPath 这些通用工具

    3. 页面正文内容不要再回到这里集中维护

  9. 其他

    1. 全局样式 src/styles
    2. 字体资源 src/fonts
    3. 静态资源 / 图片 src/assets
    4. 构建配置 astro.config.mjs

新增页面 quick 'n dirty

  1. src/contents 新建一个同 slug 文件
  2. 在 [[lang]/[...slug].astro](<src/pages/[lang]/[...slug].astro>) 里注册这个 slug
  3. 如果希望无语言前缀也能访问,在 [[...slug].astro](<src/pages/[...slug].astro>) 里也加上这个 slug
  4. 内容写在 contents,结构拆到 components

贡献时尽量保持

  1. 改动尽量小而准
  2. 命名尽量直接,不要为了“抽象”而抽象
  3. 如果你改了路由、contents 结构或 i18n 约定,请顺手更新这个文件