# cornhsu-polymigrate 中文文档

规范地址：https://npmcn.com/package/cornhsu-polymigrate/

版本：4\.0\.0
npm 元数据更新时间：2026-11-03T08:31:34.538Z
中文译文更新时间：2026-11-03T09:44:56.117Z
软件包许可：MIT

本文由上游 README 机器翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/cornhsu-polymigrate
原文对照：https://npmcn.com/package/cornhsu-polymigrate/?lang=original
项目主页：https://cornhsu.com/polymigrate
源码仓库：https://github.com/HSU-YU-MING/cornhsu-polymigrate

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：40.1 kB，5 个文件
- TypeScript 类型：未声明
- Node.js 要求：\>=18
- 运行依赖：0 个
- 首次发布：2026-07-22T17:54:57.682Z
- 最新版本发布：2026-11-03T08:31:34.055Z
- 已发布版本数：12（近 12 个月 12 个）

## 中文简介

i18n-first静态站点迁移器—唯一一个可以自动对多语言页面进行配对的迁移器。将遗留站点镜像为frontmatter Markdown，自动匹配语言版本，并诚实地列出无法配对的内容。

## 安装

```sh
npm install cornhsu-polymigrate
```

也可以使用：`pnpm add cornhsu-polymigrate`、`yarn add cornhsu-polymigrate`、`bun add cornhsu-polymigrate`

## README

# PolyMigrate

[![NuGet](https://img.shields.io/nuget/v/Cornhsu.PolyMigrate.svg?label=Cornhsu.PolyMigrate)](https://www.nuget.org/packages/Cornhsu.PolyMigrate) [![Downloads](https://img.shields.io/nuget/dt/Cornhsu.PolyMigrate.svg)](https://www.nuget.org/packages/Cornhsu.PolyMigrate) [![CI](https://github.com/HSU-YU-MING/cornhsu-polymigrate/actions/workflows/ci.yml/badge.svg)](https://github.com/HSU-YU-MING/cornhsu-polymigrate/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/HSU-YU-MING/cornhsu-polymigrate/blob/main/LICENSE)

> **i18n-first静态站点迁移器** -唯一的网站迁移，配对您的多语言页面自动。

**[帐面价值的项目](https://cornhsu.com/polymigrate) · [NuGet](https://www.nuget.org/packages/Cornhsu.PolyMigrate) · [繁體中文說明](https://github.com/HSU-YU-MING/cornhsu-polymigrate/blob/main/README.zh-Hant.md) ·麻省理工学院**

PolyMigrate将遗留的动态站点（旧的PHP站点等）转换为干净的静态站点 Markdown——它将多语言内容视为头等大事，而不是事后才想到的。 配置驱动，完全脱机可运行，构建在。net上。

**状态:3.0。** 提取管道、配对、验证、缩略图和孤儿页面 完成恢复，并根据真正的全站点迁移进行验证（见下文）。这个 **CLI 表面、退出代码、阶段输出合同和YAML配置被冻结在一个主版本中**： 新功能会对小版本产生影响，修复会对补丁产生影响，任何改变其中一个的东西都会产生影响 四面等待少校。 **3.0就是这样一个版本** -在某些情况下它会改变退出代码 所以他们遵循0 / 1 / 2 / 130契约(一个孤儿探针，没有可用的答案，一个失败的 NPM启动器和一个中断的命令不再看起来像成功)，给每个部分自己的 孤儿蛞蝓名单(`orphan_slugs.<section>.txt`)，保持动画GIF/WebP缩略图动画，和 向库中添加探测/获取入口点和可取消的重载。配置字段、CSV列 和前文字段是不变的，但配置与一个无效的值(一个CSS选择器，一个正则表达式，一个 不是单个段的路径，格式错误的URL或语言标记，没有值的键…) 当它被每个命令加载时被拒绝，而不是在某个页面或命令碰巧使用它时被拒绝 只有一些候选人没有答案（列表是书面的，但可能不完整）。 **升级前请阅读CHANGELOG中的3.0升级清单**。 早期历史：2.0是一个工程版本——它缩小了 `Cornhsu.PolyMigrate.Core` 公众。. NET API的预期入口点，并删除未使用 配置字段;2.1修复了发布管道（arm64 NPM包，符号包） npm启动器只能启动2.3.1以后的Windows/Linux arm64版本。 封闭了一个盲区 `verify` -没有链接的页面被报告为良好，因为a 链接跟踪审计从未到达它们-并添加 `slugs` 跟踪源站点 这还在更新中。 **升级到2.2可以改变一个传球 `verify` 进入1号出口**。 2.3读取源站点自己的 `hreflang` 声明（见下文），并在新的 `hreflang_map.csv`． 看到 [更新日志](https://github.com/HSU-YU-MING/cornhsu-polymigrate/blob/main/CHANGELOG.md) 查看迁移说明。

## 为什么

每个多语种机构网站（政府、大学、非政府组织、宗教组织） 面临着同样痛苦的迁移步骤：手动匹配每个页面的语言版本。 没有现有的工具可以解决这个问题——通用的抓取器每次提取一个页面，然后离开 配对给你。PolyMigrate:

-   **对自动** 其中文件名是对称的(`/ch/news/x` ↔ `/en/news/x` 共享一个 `translation_key`)，
-   **阅读网站自己的内容 `hreflang` 声明** - - - - - - `<link rel="alternate" hreflang>` 就是那个 配对标志着网站的作者 _声明_ 而不是工具推断出来的东西 先试过，可以跨部分配对(`/ch/news/` ↔ `/en/press/`)，
-   **启发式建议配对** 两者都不适用的情况-仅在分离器上不同的鼻涕虫 （`2025-light-offering` vs `2025_light_offering`)，共享相册，隐藏规范化日期 在蛞蝓(`20240121` vs `01212024`)、标题相似度；
-   **诚实地报告它不能配对的东西**，生成一个评审就绪的差距清单，而不是 猜错了。

注意PolyMigrate故意做了什么 _不_ 是否：通过URL字符串匹配语言版本 相似点。 `/products/`， `/produkte/` 和 `/產品/` 相似度为0并且是相同的 页面;对称路径配对是去掉语言前缀后的精确匹配，而不是 模糊的一个。

语言不限于两个：声明任何数字 `lang_map` 每个输出 （frontmatter, inventory, pair）也随之扩大。所有语言环境输出都是标准的BCP-47。

### 关于 `hreflang`

遗留站点就是那些具有以下特性的站点 `hreflang` 是缺失还是错误——通常是由 几年后成为SEO承包商所以PolyMigrate把它当作有力的证据，而不是福音。 声明仅用于配对，如果它：

-   不是 `x-default` （这是“当没有匹配的时候去哪里”，不是语言版本），
-   并不指向页面本身，
-   解析到实际在您的镜像中的页面 **包含同一主机**，因为很多网站把 英文版本为 `en.example.org`，其中仅路径比较将使页面成为其 自己的翻译,
-   两端都有内容页——两端都不是站点级页面(语言选择器和 比如，这不是任何人的翻译)，
-   和 **并不是许多相同语言的页面声称同一目标之一**． 这是经典的 失败:一个 `<link>` 粘贴到站点范围的模板中，因此每个中文页面都声明 英文主页作为其英文版。一页不能翻译另外三页， 因此，所有这些要求都被放弃了，而不是变成了看起来自信的错误组合。

所有声明的内容——包括被拒绝的内容——都被写入 `hreflang_map.csv` 与 `in_mirror` / `reciprocal` / `usable` 和一个 `reject_reason` 命名失败的规则，因为 “我能相信这个网站的hreflang吗？”是一个你想用数据而不是总数来回答的问题。

对仍然只有永远 _建议_： `hreflang` 提高证据质量，却没有 将该工具切换为自己合并页面。这是一个深思熟虑的决定，而不是一个未完成的决定 一是它背后的测量，以及需要改变什么才能重新审视它，这些都被记录下来 [doc /hreflang\_](https://github.com/HSU-YU-MING/cornhsu-polymigrate/blob/main/docs/hreflang_%E9%87%8F%E6%B8%AC%E8%88%87%E6%B1%BA%E7%AD%96.md)。

## 一些久经沙场的违约

提取管道包含在实际迁移过程中发现的实际问题的修复程序 通用工具和LLM提取器会悄悄地出错：

| 现实世界的坑 | 内置的处理 |
| --- | --- |
| 手机照片横向/颠倒缩略图 | 调整大小前的EXIF自动定向 |
| 标题带有冒号/带前导零的数字 | yaml库转义，强制引用 |
| `%20` 图像路径的双重编码 | 在磁盘上解码，在url中单独编码 |
| 降低转换器掉落视频/ iframes / pdf | 占位符往返保持嵌入到位 |
| `<title>` 被日期和厂名污染了 | 主体优先的标题提取+可配置的清理 |
| 混合日期格式(`YYYYMMDD` / `MMDDYYYY` / `DDMMYYYY`） | 所有的识别和标准化 |
| 旧文章从索引中删除，但仍在使用 | 孤立探测（每天的URL候选对象+后缀变体） |
| `hreflang` 指向失效url、其他主机或自身 | 对着镜子验证；不可用的记录，不应用 |
| 源站点上的破碎图像 | 检测，记录，从不阻止运行 |
| Bot保护（JS cookie挑战→409） | 配置中的声明式cookie解决方案 |
| 遗留编码（Big5, GB2312，…） | 每个站点声明或默认 |

## 案例研究：完整的寺庙站点迁移

PolyMigrate的管道是完成实际迁移的产品化版本 （中英双语佛寺网站）：

-   **516页** 镜像和提取， **4.6 GB** 的媒体
-   **281个翻译键**； **231篇双语文章自动配对** 通过对称路径
-   内置验证器: **检查了1,269个内部链接+ 4,116个媒体引用- 0错误**
-   通过日期探测回收了13件孤儿物品；141张exif旋转照片固定在缩略图中

最初的Python原型的输出被用作移植时的黄金基线：466/516 提取的正文在空格归一化后是字节相同的，其余部分是 渲染等效或严格地更忠实。

还有两个数字：

-   **重新运行速度快了7倍**：媒体哈希被缓存 `(size, mtime)`进行了一次完整的重跑 4.6 GB的站点 **从30.1秒下降到4.6秒**。
-   **输出可以按原样部署**： `redirect_map` 自动填充新路径，和 PolyMigrate同时发射两个 **nginx相依** 和一个 **Netlify `_redirects`** 锉刀 花了半天手写的301来复制一个文件。

## 安装使用

两个通道-选择您已经拥有的运行时。 **同样的工具，同样的行为。**

```
npx cornhsu-polymigrate extract site.yaml   # Node — no .NET install needed
dotnet tool install -g Cornhsu.PolyMigrate  # .NET 10
```

> npm构建附带了一个独立的本机二进制文件，并且只下载其中一个 匹配您的平台（win32 / Linux / darwin，每个都是x64和arm64）。 一个例外: `thumbs` 不能在Intel mac （darwin-x64）上运行，因为Magick。净15, 它背后的图像库，不再为他们提供构建；它退出时有一个解释。 所有其他命令都在那里工作；在英特尔Mac上使用缩略图，请使用3.0.x。 迁移站点通常是一次性的工作——为一个站点安装整个SDK 跑步是大多数人无法接受的摩擦，所以工具会满足你的需求。

```
dotnet tool install -g Cornhsu.PolyMigrate
polymigrate extract site.yaml               # mirror HTML -> frontmatter Markdown + inventories
polymigrate verify .                        # link/media/frontmatter/unlinked-page audit, CI exit codes
polymigrate thumbs site.yaml                # EXIF-corrected, width-capped thumbnails
polymigrate probe-orphans site.yaml --section news --years 2021-2023   # -> orphan_slugs.news.txt
polymigrate fetch-orphans site.yaml --section news                      # reads orphan_slugs.news.txt
polymigrate slugs . --section news          # slugs already mirrored under ./raw (pipeable)
```

> **动画GIF/WebP缩略图保持每帧-在限制内。** 缩放动画帧 帧消耗的内存和时间与帧×宽×高成比例（测量：400帧） 1300×900 GIF花了39秒和3.2 GB)。动画结束 **50个像素** 总的来说，或一个 动画缩略图会比原来的大，得到的是第一帧缩略图 与3.0之前的结果相同（不需要缩放的动画会按原样复制）。在极限情况下，它需要大约6秒和250 - 400mb的内存峰值，具体取决于内容 （两个100帧1000×500动图分别为250 MB和384 MB）。这个 `thumbs` 摘要列表 哪些文件有第一帧，为什么；这两种情况都不是失败或更改退出代码。 静止图像也有限制：1 / 1 **179像素** (枕头的减压炸弹阈值- 一个270kb的GIF可以声明20000×20000，解码它需要14.8秒和1.6 GB)根本无法解码 作为一个失败的缩略图（出口1）。1亿像素的相机原件很好。

> **`raw/` 是你无法重生的东西。** 重新爬取一个网站一次需要几个小时 礼貌的请求率，并且源站点可能在您完成的那一刻被关闭 迁移——此时你的镜像是唯一剩下的副本。无PolyMigrate命令 永远删除或覆盖 `raw/` 或 `media/`;保留它们，直到对迁移进行签名 关掉，如果源消失，备份它们。

> 没有。net ?上面的每个命令也运行 **零安装** 通过NPM -只需加上前缀： `npx cornhsu-polymigrate extract site.yaml`， `npx cornhsu-polymigrate verify .`等等。

每个站点一个YAML配置描述所有与站点相关的内容——参见 [例子/ ibps-austin.yaml](https://github.com/HSU-YU-MING/cornhsu-polymigrate/blob/main/examples/ibps-austin.yaml) 对于一个完全注释的实际示例。

```yaml
config_version: 1
site:
  base_url: https://legacy.example.org
url_pattern:
  lang_map: { ch: zh-Hant, en: en }     # any number of languages
  default_lang: zh-Hant
  strip_extensions: [.php]
extract:
  content: "section[id]:not(#header):not(#footer)"
pairing:
  fallback: [hreflang, slug_normalized, shared_media, date, title_similarity]
```

## 用作库

CLI是一层薄薄的外壳 `Cornhsu.PolyMigrate.Core`． 来驱动你自己的迁移 ．. NET代码，使用 `PolyMigrator` 外观-单一文档化入口点：

```
dotnet add package Cornhsu.PolyMigrate.Core
```

```csharp
using PolyMigrate.Core;

var migrator = PolyMigrator.FromConfigFile("site.yaml");
var report = migrator.Extract("out/");        // out/raw, out/media -> out/content + inventories
if (report.HasErrors) { /* unsafe paths were skipped; see path_issues.csv */ }

var verify = PolyMigrator.Verify("out/");      // no config needed; reads Phase 2 output only
Console.WriteLine($"{verify.Errors} errors, {verify.Warnings} warnings");

// Orphan pages (probe-orphans / fetch-orphans). Nothing is written until you decide to.
var probe = await migrator.ProbeOrphansAsync("out/", "news", 2021, 2023);
if (probe.NoUsableAnswers) { /* the site never answered: an empty list means nothing */ }
else { await migrator.FetchOrphansAsync("out/", "news", probe.Found); }
```

Extract， Verify和GenerateThumbnails也有重载 `CancellationToken` （探测/获取方法将一个作为最后一个参数）。

## 布局

| 路径 | 目录 |
| --- | --- |
| `src/PolyMigrate.Core` | 提取/配对/验证库(NuGet： `Cornhsu.PolyMigrate.Core`） |
| `src/PolyMigrate.Cli` | 这个 `polymigrate` CLI （NuGet）工具包： `Cornhsu.PolyMigrate`） |
| `tests/` | 单元/集成测试+具有金文件基线的离线夹具站点 |
| `docs/contracts.md` | 管道阶段之间的文件格式契约 |
| `docs/hreflang_量測與決策.md` | 为什么 `hreflang` 只 _建议_ ——这通电话背后的衡量标准 |
| `docs/搬遷工具_評估與規劃書.md` | 原始的设计/规划文件 `§X.Y` 整个参考资料的来源点在这里) |

## 发展

```
dotnet build
dotnet test
dotnet run --project src/PolyMigrate.Cli -- --help
```

## 看到也

[**多語言網站搬遷最容易搬丟的東西**](https://cornhsu.com/articles/multilingual-site-migration-pairing) （繁体中文）-范畴的背景，而不是这个工具：五配对 信号按优先顺序排列，为什么“刚读” `hreflang`“经常错过真正的遗产网站 (一页528页， **0** 声明（sitemap 404），声明必须通过的五道门 在它可用之前传递，以及为什么URL字符串相似性是这个工作的错误工具。

许可: [麻省理工学院](https://github.com/HSU-YU-MING/cornhsu-polymigrate/blob/main/LICENSE)． 所有依赖是MIT/BSD/Apache-2.0 (成像通过 **魔法。网**;imagessharp在4岁时被删除。X线开始需要a 构建时的许可密钥)。看到 [THIRD-PARTY-NOTICES](https://github.com/HSU-YU-MING/cornhsu-polymigrate/blob/main/THIRD-PARTY-NOTICES.md)。

PolyMigrate从您指向的站点获取页面，并且可以配置为发送 饼干通过机器人挑战。 **它假定站点是您的，或者您正在进行迁移 得到了业主的许可** ——这就是它的作用。检查源站点的条款 然后再指着别的东西。

## 常见问题

### cornhsu-polymigrate 是什么？

i18n-first静态站点迁移器—唯一一个可以自动对多语言页面进行配对的迁移器。将遗留站点镜像为frontmatter Markdown，自动匹配语言版本，并诚实地列出无法配对的内容。

### 如何安装 cornhsu-polymigrate？

在项目目录运行 npm install cornhsu-polymigrate，或使用 pnpm add / yarn add / bun add。它还提供命令行工具 polymigrate，可以用 npx polymigrate 直接运行。

### cornhsu-polymigrate 支持 TypeScript 吗？

该包的 package\.json 没有声明类型入口。需要类型提示时，可以在 npm 上查找社区维护的 @types/cornhsu-polymigrate 是否存在。

### cornhsu-polymigrate 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=18。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### cornhsu-polymigrate 可以商用吗？

cornhsu-polymigrate 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### cornhsu-polymigrate 还在维护吗？

最新版本 4\.0\.0 发布于 2026/11/03（今天）；至今共发布 12 个版本，其中过去 12 个月发布了 12 个；首次发布于 2026/07/23。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

