Skip to content

内容迁移工具

从其他平台迁移内容到 VitePress 时,可以使用以下自动化工具和方案,减少手动工作量。

迁移概览

mermaid
graph LR
    Source[源平台] --> Extract[提取内容]
    Extract --> Convert[格式转换]
    Convert --> Structure[目录重组]
    Structure --> Import[导入 VitePress]
    Import --> Verify[验证结果]

从 WordPress 迁移

使用 wordpress-export-to-markdown

bash
npx wordpress-export-to-markdown \
  --input=wordpress.xml \
  --output=docs/ \
  --frontmatter=true \
  --year-month-prefix=true

手动迁移步骤

  1. 导出 WordPress 内容

在 WordPress 后台:工具 → 导出 → 选择「所有内容」→ 下载 XML 文件

  1. 转换格式
bash
# 安装转换工具
npm install -g wordpress-markdown-exporter

# 转换
wordpress-markdown-exporter --input=wordpress.xml --output=posts/
  1. 整理目录结构
bash
# 将文章移入 VitePress 项目
mkdir -p docs/blog
mv posts/*.md docs/blog/
  1. 修复 Frontmatter

WordPress 导出的 Frontmatter 可能需要调整:

yaml
# 原始(WordPress 格式)
date: 2024-01-15 10:30:00 +0800
categories: [技术, 前端]
tags: [VitePress, Vue]

# 调整为 VitePress 格式
date: 2024-01-15
tags:
  - VitePress
  - Vue

自动化脚本

typescript
// scripts/fix-frontmatter.ts
import fs from 'fs'
import path from 'path'

function fixFrontmatter(filePath: string) {
  let content = fs.readFileSync(filePath, 'utf-8')
  
  // 修复日期格式
  content = content.replace(
    /date:\s*(\d{4}-\d{2}-\d{2})\s+\d{2}:\d{2}:\d{2}.*/g,
    'date: $1'
  )
  
  // 修复分类为标签
  content = content.replace(
    /categories:\s*\[(.+)\]/g,
    'tags:\n  - $1'
  )
  
  fs.writeFileSync(filePath, content)
}

// 批量处理
const dir = 'docs/blog'
fs.readdirSync(dir)
  .filter(f => f.endsWith('.md'))
  .forEach(f => fixFrontmatter(path.join(dir, f)))

从 GitBook 迁移

使用 gitbook-to-vitepress

bash
npx gitbook-to-vitepress --input=./gitbook --output=./docs

手动迁移要点

GitBook 特性VitePress 对应说明
SUMMARY.mdsidebar 配置自动转换为侧边栏
{% hint %}::: tip自定义容器语法不同
{% code %}```lang代码块语法
{{ book.variable }}Vue 模板语法变量引用方式不同

SUMMARY.md 转换脚本

typescript
// scripts/convert-summary.ts
import fs from 'fs'

function convertSummary(summaryPath: string) {
  const content = fs.readFileSync(summaryPath, 'utf-8')
  const lines = content.split('\n')
  const sidebar: any[] = []
  
  for (const line of lines) {
    const match = line.match(/^\s*-\s*\[(.+?)\]\((.+?)\)/)
    if (match) {
      sidebar.push({
        text: match[1],
        link: match[2].replace(/\.md$/, '')
      })
    }
  }
  
  return sidebar
}

const sidebar = convertSummary('gitbook/SUMMARY.md')
console.log(JSON.stringify(sidebar, null, 2))

从 Docusaurus 迁移

主要差异对照

特性DocusaurusVitePress
配置文件docusaurus.config.js.vitepress/config.mts
文档目录docs/docs/
博客目录blog/需自行搭建
Frontmatter支持支持
MDX支持不支持(用 Vue 组件替代)
侧边栏自动生成手动配置或使用插件

MDX 转换

Docusaurus 的 MDX 文件需要转为 Vue 组件:

bash
# 将 .mdx 改为 .md
find docs -name "*.mdx" -exec bash -c 'mv "$1" "${1%.mdx}.md"' _ {} \;

配置转换要点

typescript
// Docusaurus 配置
// docusaurus.config.js
module.exports = {
  title: 'My Site',
  themeConfig: {
    navbar: {
      items: [
        { label: 'Docs', to: '/docs' }
      ]
    }
  }
}

// 对应的 VitePress 配置
// .vitepress/config.mts
export default defineConfig({
  title: 'My Site',
  themeConfig: {
    nav: [
      { text: 'Docs', link: '/docs/' }
    ]
  }
})

从 Notion 迁移

使用 notion-to-md

bash
# 安装
npm install notion-to-md

# 导出
npx notion-to-md --token=NOTION_TOKEN --database_id=DB_ID --output=docs/

注意事项

Notion 特性处理方式
数据库页面导出为单独 Markdown 文件
嵌入块需手动转换为链接或组件
代码块保留语言标识
图片下载到本地或使用图床
关联页面转换为内部链接

通用迁移工具

Pandoc — 万能格式转换

bash
# HTML 转 Markdown
pandoc input.html -t markdown -o output.md

# Word 转 Markdown
pandoc input.docx -t markdown -o output.md

# LaTeX 转 Markdown
pandoc input.tex -t markdown -o output.md

# 批量转换
find . -name "*.html" -exec bash -c 'pandoc "$1" -t markdown -o "${1%.html}.md"' _ {} \;

Frontmatter 批量生成

typescript
// scripts/generate-frontmatter.ts
import fs from 'fs'
import path from 'path'

function addFrontmatter(filePath: string) {
  let content = fs.readFileSync(filePath, 'utf-8')
  
  // 跳过已有 frontmatter 的文件
  if (content.startsWith('---')) return
  
  // 从文件名生成标题
  const fileName = path.basename(filePath, '.md')
  const title = fileName
    .split('-')
    .map(word => word.charAt(0).toUpperCase() + word.slice(1))
    .join(' ')
  
  const frontmatter = `---
title: ${title}
description: ${title}的详细说明
date: ${new Date().toISOString().split('T')[0]}
---

`
  
  content = frontmatter + content
  fs.writeFileSync(filePath, content)
}

// 批量处理
const dir = 'docs/guide'
fs.readdirSync(dir)
  .filter(f => f.endsWith('.md'))
  .forEach(f => addFrontmatter(path.join(dir, f)))

迁移检查清单

完成迁移后,逐项检查:

内容完整性

  • [ ] 所有页面都已迁移
  • [ ] 图片资源路径正确
  • [ ] 内部链接有效
  • [ ] Frontmatter 格式正确
  • [ ] 代码块语言标识正确

功能验证

  • [ ] 导航栏链接正常
  • [ ] 侧边栏显示正确
  • [ ] 搜索功能可用
  • [ ] 暗色模式正常
  • [ ] 移动端显示正常

SEO 检查

  • [ ] 每页有 title 和 description
  • [ ] URL 结构合理
  • [ ] 无 404 链接
  • [ ] 图片有 alt 文本

常见问题

迁移后构建报错

常见原因及解决方法:

错误原因解决方案
Unexpected tokenMDX 语法未转换将 JSX 替换为 Vue 模板
Invalid frontmatterYAML 格式错误检查缩进和特殊字符
Image not found图片路径错误移动图片到 public/ 目录

图片迁移方案

bash
# 方案 1:下载到本地
wget -r -l1 -nd -A jpg,png,svg -P docs/public/images/ https://example.com/images/

# 方案 2:使用图床
# 配置图床后,批量替换图片 URL

大规模迁移建议

对于 100+ 页面的大规模迁移:

  1. 先迁移核心页面(首页、指南)
  2. 建立自动化脚本处理重复工作
  3. 分批迁移,每批验证后再继续
  4. 保留旧站并行运行一段时间
  5. 设置 301 重定向保持 SEO

相关链接

贡献者

加载中...

想要成为贡献者?

在 CNB 上参与贡献