DragonRster`s Void
Banner Image
目录
脚本详解:rebuild-all.ps1

全站构建编排器 —— 按正确顺序调度一切


rebuild-all.ps1 是整个构建系统的顶层入口。它本身不生成任何页面——它是一个"指挥家",负责按正确的依赖顺序调用其他脚本,确保每一步的前置条件都得到满足。它是你运行 build.cmd 时实际执行的脚本。

1. 整体流程

整个构建流程有严格的顺序要求,下面是完整的调用链:


1. generate-archive.ps1           ← 生成 latest-posts + archive + tags + 搜索索引
       │
       ▼
2. build.ps1 (index)              ← 中文首页
3. build.ps1 (blog-*) × N        ← 所有中文博客页面
       │
       ▼
4. build.ps1 (index, -Lang en)    ← 英文首页
5. build.ps1 (blog-*, -Lang en)×N ← 所有英文博客页面
6. generate-archive.ps1 -Lang en  ← 英文归档/标签
       │
       ▼
7. generate-rss.ps1               ← RSS 2.0 订阅源
8. generate-sitemap.ps1           ← sitemap.xml

为什么是这个顺序?因为每一步都依赖前一步的产出

  • build.ps1 需要 latest-posts.html(由步骤 1 生成)
  • RSS 和 sitemap 需要所有博客页面已经构建完成(步骤 2-6),才能扫描到最新的文件时间戳
  • 英文归档需要英文博客已经构建完成,才能提取元数据
  • 2. 代码结构

    脚本接受一个可选参数 -IncludeDrafts,传递给下游所有构建步骤:

    
    param([switch]$IncludeDrafts)
    

    每个步骤的结构基本相同:

    
    if (Test-Path $targetScript) {
        Write-Host "描述..." -ForegroundColor Yellow
        & $targetScript -参数
    } else {
        Write-Host "警告: 找不到脚本 $targetScript" -ForegroundColor Red
    }
    

    这种"先检查,再执行"的模式确保了即使某个脚本文件被意外删除,构建流程也不会崩溃——只是跳过该步骤并给出警告[1]

    3. 首页构建

    首页使用固定的内容文件,不需要扫描目录:

    
    # 中文首页
    & $buildScript -PageName "index" -Title "DragonRS Void"
        -ContentFile "$pagesDir\index\content-index.html"
        -IncludeDrafts:$IncludeDrafts
    
    # 英文首页
    & $buildScript -PageName "index" -Title "DragonRS Void"
        -ContentFile "$pagesDir\index\content-index-en.html"
        -Lang en
    

    注意英文首页没有 -IncludeDrafts 参数——因为英文翻译默认都是已发布状态。如果将来需要英文草稿,可以加上。

    PageName"index" 时,输出路径是项目根目录(中文)或 dist/en/(英文),而不是 dist/ 子目录[2]

    4. 博客文章批量构建

    中文博客的构建自动扫描目录,排除英文文件:

    
    $blogFiles = Get-ChildItem "$blogDir\content-*.html"
        | Where-Object { $_.Name -notmatch '-en\.html$' }
    
    foreach ($file in $blogFiles) {
        $baseName = $file.BaseName -replace '^content-', ''
        $pageName = "blog-$baseName"
        # 从文件中提取 title 元数据
        $titleMatch = [regex]::Match($raw, '')
        $title = if ($titleMatch.Success) { $titleMatch.Groups[1].Value }
                 else { $baseName }
        & $buildScript -PageName $pageName -Title $title
            -ContentFile $file.FullName -IncludeDrafts:$IncludeDrafts
    }
    

    关键细节:

  • 使用 -notmatch '-en\.html$' 排除英文文件——因为英文文章现在放在 blog/en/ 子目录而非加 -en 后缀,这个过滤实际上是为了向后兼容旧文件[3]
  • 标题从元数据提取而非文件名推断——这使得标题可以包含任意字符,且与文件名解耦
  • $IncludeDrafts 以 switch 形式传递:-IncludeDrafts:$true-IncludeDrafts:$false
  • 5. 英文内容处理

    英文内容的处理分为两个部分:

    Part 1 — 构建英文页面:

    
    $enBlogDir = "$pagesDir\blog\en"
    $enFiles = Get-ChildItem "$enBlogDir\content-*.html"
    foreach ($file in $enFiles) {
        $baseName = $file.BaseName -replace '^content-', ''
        $pageName = "blog-$baseName"
        & $buildScript -PageName $pageName -Title $title
            -ContentFile $file.FullName -Lang en
    }
    

    Part 2 — 生成英文归档/标签:

    
    & $archiveScript -Lang en
    

    英文归档必须在英文页面构建之后运行——因为 generate-archive.ps1 -Lang en 扫描 blog/en/ 目录下的文件,提取元数据来生成归档和标签。如果先运行归档再构建页面,归档内容将不包含最新的文章。

    6. 最后的收尾:RSS 和 Sitemap

    所有页面构建完成后,最后两步是生成 RSS 和 sitemap:

    
    & $rssScript        # generate-rss.ps1  → dist/rss.xml
    & $sitemapScript    # generate-sitemap.ps1 → sitemap.xml
    

    这两个文件是元数据文件——它们描述整个网站的结构,供 RSS 阅读器和搜索引擎爬虫使用。它们必须在所有页面构建完成后生成,以确保收录的 URL 列表和内容是最新的[4]

    RSS 和 sitemap 的生成逻辑各自独立——它们之间没有依赖关系,可以并行执行。但由于 PowerShell 单线程调用,目前是串行的。

    7. 设计理念

    rebuild-all.ps1 的名中"all"意味着它构建所有东西。这是一个故意的设计选择——没有"增量构建"、没有"仅构建变更"、没有"缓存"。原因有三:

  • 站点规模小。不到 20 篇文章,全量构建只需不到 10 秒。增量构建带来的复杂度不值得
  • 侧边栏是全局状态。留言板、更新日志、最新文章——这些出现在每一页上。改变一处就意味着所有页面都需要更新
  • 简单即可靠。没有缓存失效问题,没有脏读,没有"为什么改了文章但归档页没更新"的困惑——每次构建都是清洁的完整输出
  • 这种"全量构建"的哲学,和很多现代静态站点生成器(如 Jekyll、Hugo)是一致的——只不过它们用 Go/Ruby 写,而我们用 PowerShell[5]

    小结

    rebuild-all.ps1 的代码量是五个脚本中最少的(约 110 行),但它是唯一"了解全局"的脚本——它知道哪些脚本存在、它们的依赖关系、以及正确的调用顺序。新增一个脚本时(比如将来增加 generate-og-image.ps1),只需要在对应的位置插入调用即可。

    最后有一点值得注意:每个步骤执行后都会输出一行带颜色的状态信息(-ForegroundColor Yellow/Green/Red),让你在终端中一眼就能看到构建进度——这是 CLI 工具的"人性化设计",哪怕它只面向开发者[6]


    [1]实际上,generate-archive.ps1 找不到时只是警告,而 build.ps1 找不到会导致大量页面缺失——因为所有单页面构建都依赖它。但系统不会直接崩溃,这是"优雅降级"的体现。

    [2]build.ps1 的输出逻辑是:index → 项目根目录 index.html;中文其他页面 → dist/;英文所有页面 → dist/en/

    [3]在早期的双语实现中,英文文章使用 content-*-en.html 后缀放在 blog/ 目录下。后来迁移到了 blog/en/ 子目录方案。这次重构是"目录优于后缀"原则的体现——用目录结构表达语言归属,而非文件名约定。

    [4]RSS 和 sitemap 的生成脚本各自独立运行,不需要 rebuild-all.ps1 传递任何参数。generate-sitemap.ps1 通过扫描 dist/ 目录获取已构建的文件列表。

    [5]PowerShell 实际上比很多现代构建工具更适合这种任务——它原生支持 XML 操作、文件系统遍历、管道处理,而且 Windows 系统自带,不需要安装任何依赖。

    [6]状态信息的颜色选择也有讲究:黄色用于"正在做某事",绿色用于"完成了",红色用于"出错了"——这是 CLI 工具的通用约定,来自交通灯的颜色语义。


    « 脚本详解:generate-archive.ps1 —— 归档、标签与搜索索引 返回主页 脚本详解:generate-rss.ps1 —— RSS 2.0 订阅源生成 »
    English

    搜索

    最新文章

    » 脚本详解:build.ps1
    » 脚本详解:gener...
    » 脚本详解:gener...
    » 脚本详解:rebui...
    » 脚本详解:gener...

    » 文章归档


    本文标签

    教程 网站建设 脚本


    功能

    » RSS 订阅
    » GitHub 源码
    » 返回顶部
    » 文章归档


    DRAGONRSTER
    CC BY-NC-SA
    © 2004-2026 DragonRster • Made with HTML • 本站支持IE5.5+
    最佳浏览分辨率:1024x768 • 最后更新于 2026年04月29日 02:05:28