Skip to content

站点 URL 没有单一来源:19 处手写 /${lang}/… 散在 14 个文件,React 侧还有一份从未执行的兜底实现 #49

Description

@SongshGeo

「一个 collection 的条目 URL 长什么样」这件事,在 14 个文件里各写了一遍,一共 19 处。

证据

src/utils/relations.ts:246              `/${lang}/${collection}/${slug}`   ← 唯一一处真正的实现
src/pages/[lang]/index.astro:74          `/${lang}/projects/${entrySlug(project)}`
src/pages/[lang]/projects/index.astro:73 `/${lang}/projects/${entrySlug(project)}`
src/pages/[lang]/people/index.astro:48   `/${lang}/people/${slug}`
src/pages/[lang]/news/index.astro:40     `/${lang}/people/${person.slug}`
src/pages/[lang]/library/index.astro:28  `/${lang}/library/${slug}`
src/pages/[lang]/research/index.astro:45 `/${lang}/research/${entrySlug(theme)}`
src/pages/[lang]/resources/index.astro:69 `/${lang}/resources/${resource.slug}`
src/pages/[lang]/publications/index.astro:27 `/${lang}/publications/${pub.data.bib_key ?? pub.id}`
src/pages/[lang]/library/[...slug].astro:129 `/${lang}/library`
src/components/Header.astro:22           `/${lang}/`

grep -rn '\${lang}/' src → 19 处。)

更糟的是 React 侧又算了第二遍

服务端算好 detailUrl 塞进 props,客户端组件却不信它,自己再拼一次兜底:

// HomePage.tsx:106
href={project.detailUrl || `/${lang}/projects/${project.id}`}
// PeoplePage.tsx:19
href={person.detailUrl || `/${lang}/people/${person.id}`}
// ProjectsPage.tsx:35, LibraryPage.tsx:26 同样

这些兜底目前算出来的 URL 和主路径一致,所以没在线上出事——但那是巧合:它成立
的前提是 view model 的 id 恰好就是 slug,而各个 collection 并不一致
(publications 按 citation key,library 用的是 slug 字段而不是 id)。这是一份
从来没有被执行、因此也从来没有被验证过的第二实现,路由形状一改它就会静默地
指向 404。

建议

抽一个路由模块,让它成为唯一知道 URL 形状的地方:

// src/routes.ts
export function href(lang: Lang, collection: RelCollection, slug: string): string;
export function indexHref(lang: Lang, collection: RelCollection): string;
export function homeHref(lang: Lang): string;

relations.ts:246 改成调它,19 处手写改成调它,React 组件的 || ... 兜底直接
删掉——props 里的 detailUrl 要么有值,要么这个条目就没有页面(publications
里没有 sidecar 的论文就是这种情况,types.ts 已经写清楚了)。

顺带一提,href 里也是唯一适合放「哪个 collection 有独立页面」这个判断的地方;
现在它散在 relations.tsspec.hasPage(data) 和各个组件的 || 里。

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