Skip to content

src/content/ 的六个软链是 content.config.ts 自己证明不需要的:为它们付出了 320 行、两处 ignore 和第五份目录映射 #45

Description

@SongshGeo

src/content/ 下的六个软链,是 content.config.ts 自己证明不需要的东西。

现状

src/content.config.ts 里有两种 base 写法,并存:

// 直接读 vault,没有软链
site:         glob({ pattern: 'site.md',        base: findContentRoot() ?? './.content' })
translations: glob({ pattern: '**/*.{zh,en}.md', base: findContentRoot() ?? './.content' })

// 必须先有软链
people:       glob({ ..., base: './src/content/people' })
projects:     glob({ ..., base: './src/content/projects' })
library:      glob({ ..., base: './src/content/library' })
research:     glob({ ..., base: './src/content/library/研究' })
resources:    glob({ ..., base: './src/content/library/资源' })
publicationHighlights: glob({ ..., base: './src/content/library/文献/精选' })

translations 集合会遍历整个 vault*.en.md,它用绝对路径就够了。
同一个 vault、同一个 glob() loader,前两行不需要软链,后六行需要——差别不在
Astro,只在这六行 base 怎么写的。

这六个软链的代价

  1. scripts/setup-content.mjs 里一个 320 行的闭包 linkCollection(L364–683,
    在一个 370 行的 setupContentCollections 里面)。它要处理:软链已存在、
    软链指向旧路径、目标是真目录、Windows/Vercel 上 symlink 不可用要退化成
    fs.cpSync、删除失败要重试三次并 sleep 递增退避、复制后要再验证一次。
    这段代码做递归删除没有任何测试,而 eslint.config.js 自己的注释
    就把「path resolution / recursive deletes」列为本仓最脆弱的代码。

  2. .gitignore 要专门写三行src/ 里的三个路径排除掉:

    src/content/people
    src/content/projects
    src/content/library
    
  3. eslint.config.js 要专门 ignore 同样三个路径,注释写着「linting them would
    walk content that this repo does not own」。

  4. src/content/ 这一层同时装了生成物和源码:三个 gitignore 的软链,和
    src/content/loaders/(745 行真源码,有测试)并排。ls src/content/ 看不出
    哪个是哪个。

  5. collection → vault 目录的映射又多了一份。 setup-content.mjs 已经
    import { BUNDLE_COLLECTION_DIRS } from '../src/utils/contentLayout.js'
    却在 L686–694 硬编码:

    await linkCollection('people',   '通讯录');
    await linkCollection('projects', '图书馆/项目');
    await linkCollection('library',  '图书馆');

    contentLayout.js 里就有 COLLECTION_VAULT_PATHS = { people: '通讯录', projects: '图书馆/项目', library: '图书馆', … }。vault 里改个目录名,
    这三行不会报错,只会安静地少建一个软链、少一整个 collection。
    i18n 收口留下的重复与死代码:OVERLAY_META、sidecar 目录、isFallback、resolveLocalized #42 数出四份映射,这是第五份;research/resources 的 base 穿过 library
    软链再拼一次子目录,是第六份。)

建议

把六个 base 改成从 vault 根算出来的绝对路径,和 site / translations 一样:

const root = findContentRoot() ?? './.content';
people: glob({ ..., base: path.join(root, COLLECTION_VAULT_PATHS.people) })

这样一次拿掉:linkCollection 的 320 行、三行 .gitignore、三行 eslint ignore、
以及第五、第六份目录映射。setup-content.mjs 只剩下它真正该干的事——把内容仓
clone 或软链到 .content/,同步 attachments。src/content/ 只剩 loaders/
是纯源码。

需要先验证的一点:astro sync 生成的 collection 类型是否依赖 base 在 src/ 下。
sitetranslations 已经不在 src/ 下且类型正常,所以大概率不依赖,但值得
在动手前跑一次确认。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    tech-debt技术债 / 重构

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions