资讯动态

Express 官网内容体系解析:Content Collections、多版本文档与多语言链接本地化

发布时间:2026/10/13 6:29:10 来源:尧图企业网站定制
文档教程技术博客【免费下载链接】expressjs.comThe Express.js Website项目地址https://gitcode.com/gh_mirrors/ex/expressjs.com点击查看免费下载本站点Express.js 官方网站仓库使用 Astro 的 Content Collections 统一管理文档、API 参考、博客与全局页面并在其上构建了一套多版本 多语言的内容组织与链接本地化机制。本文以仓库中的内容管理指南 docs/content.md 为主线结合 src/content.config.ts、src/config/versions.ts、链接本地化插件与测试等源码证据完整讲解集合划分、Frontmatter 约束、MDX 组件与代码标签页的使用以及如何新增文档版本、新增全局页面、正确编写跨语言内部链接。读完本文你将掌握为 Express 官网贡献或维护文档所需的完整实操方法并理解其底层实现原理。一、内容管理总览四类内容集合站点内容全部通过 Astro Content Collections 管理集合定义集中在 src/content.config.ts。官方指南中列出了四类核心集合集合存放位置说明docssrc/content/docs/分版本文档页各类指南 guide、入门 starter、进阶 advanced 等apisrc/content/api/分版本 API 参考文档pagessrc/content/pages/全局页面不分版本的文档、资源、支持页等blogsrc/content/blog/博客文章从源码看集合定义还包含第五个npm集合——它通过运行时请求 npm registry 获取express包的最新版本号用于版本相关信息展示const npmCollection defineCollection({ loader: async () { const res await fetch(https://registry.npmjs.org/express/latest); const { version } await res.json(); return [{ id: express, version }]; }, schema: z.object({ version: z.string() }), });四个内容集合使用统一的globloader 加载**/[^_]*.{md,mdx}模式的文件即跳过以下划线开头的文件并用 Zod schema 做运行时校验。值得一提的是官方文档中关于撰写和发布博客文章的指南对应仓库中的 src/content/blog/write-post.md 文件。二、Frontmatter Schema每个内容文件的必备元数据每个内容文件都需要在文件头部编写 frontmatter包含以下属性--- title: Page Title # 必填页面标题 description: Description # 可选用于 SEO 的页面描述 ---从 src/content.config.ts 的 schema 定义可见title为必填字符串description为可选字符串const docsCollection defineCollection({ loader: glob({ pattern: **/[^_]*.{md,mdx}, base: ./src/content/docs }), schema: z.object({ title: z.string(), description: z.string().optional(), }), });api与pages集合的 schema 与docs完全一致。blog集合则额外支持date日期自动转换为Date、tags字符串数组、cover封面图与authors作者数组含姓名与 GitHub 账号等字段供博客页面渲染使用。三、在内容中使用组件MDX需要交互式组件的内容文件必须使用.mdx扩展名而不是.md。MDX 允许你在 Markdown 内容中直接导入并使用 Astro 组件。可用组件官方指南明确登记了Alert组件组件导入方式说明Alertimport Alert from components/primitives/Alert/Alert.astro上下文提示框支持info、warning、alert三种类型完整示例--- title: My page title description: A page with alerts --- import Alert from components/primitives/Alert/Alert.astro; Regular markdown content here. Alert typeinfoThis is an informational note./Alert Alert typewarningThis is a warning message./Alert Alert typealertThis is a critical alert./Alert关键约束导入位置组件导入必须放在frontmatter 块之后、使用位置之前。不要将导入语句放在 frontmatter---块内部否则会导致解析错误。从 Alert.astro 的实现看三种类型分别对应不同的图标与默认标题info默认标题为 Notealert默认标题为 Cautionwarning默认标题为 Warning也可以通过title属性自定义标题。AlertType类型定义在 src/components/primitives/Alert/types.ts。仓库真实页面中例如 src/content/pages/en/advanced/best-practice-security.mdx 的开头就使用了Alert typeinfo来引导读者查看安全漏洞报告流程。四、代码标签页Code Tabs同一代码的多种写法展示Code Tabs 用于将同一段代码以 CommonJS / ESM / TypeScript 等变体形式放在标签页中展示。你只需给围栏代码块打上方言语言标记连续的同组代码块会自动合并成一个CodeTabs其 import 也会被自动注入无需手动导入。方言标记对照表围栏语言标签文本高亮语言cjsCommonJSJavaScriptmjsESMJavaScripttsTypeScriptTypeScript方言用法示例cjs const express require(express); const app express(); mjs import express from express; const app express(); ts import express, { Express } from express; const app: Express express(); 自定义标签对于方言之外的其他标签使用tab...元数据js tabnpm npm install express js tabpnpm pnpm add express 底层实现原理从 src/plugins/remark-code-tabs.mjs 源码可以看到该功能的完整实现逻辑分组规则LANG_TABS定义了js、cjs、mjs、ts四种方言到标签与高亮语言的映射TRIGGER_LANGScjs、mjs是触发分组的触发器。只有当连续代码块数量 2 且包含触发器或构成jsts配对时才会合并成标签页两个孤立的js块或两个孤立的ts块永远不会合并以免无关片段被错误拼接。元数据处理tab...标记会被从代码块 meta 中剥离同时保留title...等其他 meta 标记cjs/mjs会被改写为js以配合 expressive-code 高亮。Import 自动注入分组成功后插件会自动在文档根部注入import CodeTabs from components/primitives/Tabs/CodeTabs.astro;且同一文档只注入一次buildImport构造 ESTree 形式的导入节点。嵌套容器walk递归遍历 AST因此标签页可以出现在列表、引用块等嵌套容器内部。插件在 remarkmdast阶段运行早于 expressive-code 的 rehype 阶段因此每个代码块仍然获得完整的高亮与复制按钮等渲染能力。这些行为在 tests/unit/remark-code-tabs.test.mjs 中有 19 个测试用例逐一验证包括方言分组、jsts配对、元数据保留、单块不分组、嵌套容器与多组并存等场景。组件端行为渲染端组件 CodeTabs.astro 接收逗号分隔的tabs标签字符串复用Tabs原语的标签条。它还有两个贴心的交互特性跨组同步页面中所有 CodeTabs 会按标签名同步切换——读者在一处选择 ESM全页其他标签页也跟着切换到 ESM。选择持久化选择结果写入localStorage键为expressjs:code-variant下次访问同一页面会自动恢复之前的偏好。在真实文档中例如 src/content/docs/en/5x/guide/using-middleware.mdx 的中间件示例就同时给出cjs/mjs/ts三个方言版本供读者切换。另外安装命令类场景在部分页面使用专用组件PackageManagerCommand见 src/components/patterns/PackageManagerCommand/PackageManagerCommand.astro它从一条npm命令在构建期推导出 yarn / pnpm / bun 等价命令并以标签页呈现。五、API 参考集合按版本组织、仅提供英文API 参考文档位于独立的api集合src/content/api/按版本组织。与docs不同api集合不区分语言——API 参考只提供英文版本。目录结构src/content/api/ ├── 3x/ │ ├── api.mdx # API 概览 │ └── api/ │ ├── application/ # express() 与 app 方法 │ ├── middleware/ # 内置中间件 │ ├── request/ # req 对象 │ └── response/ # res 对象 ├── 4x/ │ ├── api.mdx │ └── api/ │ ├── application/ │ ├── express/ # express 模块级方法 │ ├── middleware/ │ ├── request/ │ ├── response/ │ └── router/ # Router4.x 新增 └── 5x/ ├── api.mdx └── api/ ├── application/ ├── middleware/ ├── request/ ├── response/ └── router/URL 模式带版本/en/5x/api/application→ Express 5.x 的 application API不带版本/en/api/application→ 默认指向 Express 5.x这一不带版本 URL 自动指向默认版本的规则正是多版本路由系统的核心行为之一详见下一节。六、多版本文档机制从内容目录到路由生成Express 官网同时维护多个版本的文档docs与api两个集合都按版本组织内容。版本目录结构src/content/docs/ └── en/ ├── 3x/ # Express 3.x 文档 ├── 4x/ # Express 4.x 文档 └── 5x/ # Express 5.x 文档默认版本配置的唯一事实源版本列表、前缀和默认版本只定义一次位于 src/config/versions.ts其余地方全部从这里读取VERSIONS、VERSION_PREFIXES、DEFAULT_VERSION默认版本5x是当前默认版本VERSIONS中标记isDefault: true受支持版本5x、4x、3xURL 模式带版本/en/5x/api/→ Express 5.x API 文档不带版本/en/api/→ 默认指向 Express 5.x源码中的实际定义如下export const VERSIONS: VersionOption[] [ { id: 5x, label: v5.x, isDefault: true }, { id: 4x, label: v4.x }, { id: 3x, label: v3.x (deprecated), isDeprecated: true }, ]; export const VERSION_PREFIXES: string[] VERSIONS.map((v) v.id); export const DEFAULT_VERSION: string (VERSIONS.find((v) v.isDefault) ?? VERSIONS[0]).id;添加分版本内容在对应版本目录中创建内容文件src/content/docs/en/5x/guide/my-new-page.md版本系统配置于 src/pages/[lang]/[...slug].astro会自动将该页面以/en/5x/guide/my-new-page提供为默认版本内容创建不带版本的别名 URL路由页getStaticPaths的实现确实体现了这一机制它遍历docs、api、pages三个集合为每个文件生成带版本路径对于默认版本5x的内容额外生成不带版本段的别名路径对于缺失翻译的语言还会回退使用英文内容生成路径。新增一个文档版本以6x为例创建内容目录src/content/docs/en/6x/—— 指南与文档src/content/api/6x/—— API 参考更新版本类型位于 src/config/types.tsexport type VersionPrefix 6x | 5x | 4x | 3x;将版本加入 src/config/versions.ts——这是版本列表、前缀与默认版本的唯一事实源export const VERSIONS: VersionOption[] [ { id: 6x, label: v6.x, isDefault: true }, { id: 5x, label: v5.x }, { id: 4x, label: v4.x }, { id: 3x, label: v3.x (deprecated), isDeprecated: true }, ];DEFAULT_VERSION与VERSION_PREFIXES都会从这个数组派生路由src/pages/[lang]/[...slug].astro、侧边栏以及链接本地化插件都从这里读取——因此不需要在其他地方再手动更新版本号。更新菜单版本配置位于 src/config/menu/main.ts将6x加入versioned数组docs 菜单当前为[5x, 4x]api 菜单为[5x, 4x, 3x]。审查 src/config/menu/api.ts 中的omitFrom条目判断新版本中哪些 API 特性存在或已废弃。例如当前配置中express()分组omitFrom: [3x]3.x 无此部分、内置中间件分组omitFrom: [4x, 5x]仅 3.x 存在、Router 分组omitFrom: [3x]Router 为 4.x 新增。七、全局页面非版本化文档部分文档页面在所有版本间共享不属于特定 Express 版本例如安全更新、迁移指南、性能最佳实践。这些页面放在pages集合而不是docs集合中。目录结构src/content/pages/ └── en/ ├── advanced/ │ ├── best-practice-performance.md │ ├── best-practice-security.mdx │ ├── healthcheck-graceful-shutdown.md │ └── security-updates.mdx ├── guide/ │ ├── database-integration.mdx │ ├── migrating-4.mdx │ └── migrating-5.mdx ├── resources/ │ ├── community.md │ ├── contributing.md │ ├── glossary.mdx │ ├── utils.md └── support.md以resources/开头的 slug 会被视为资源页面面包屑导航中不显示 Docs。新增全局页面在 src/content/pages/ 中创建内容文件src/content/pages/en/guide/my-global-page.md在 src/config/menu/docs.ts 中添加菜单项并标记global: true{ href: /guide/my-global-page, label: menu.myGlobalPage, ariaLabel: menu.myGlobalPageAria, global: true, }global: true标志告诉侧边栏生成链接时不加版本前缀并阻止版本切换器修改该 URL。从 src/config/menu/docs.ts 的实际配置可见/guide/database-integration、/guide/migrating-4、/guide/migrating-5以及advanced下的最佳实践与安全更新页面均已标记为global: true。八、内部链接不带语言前缀的写法与构建期自动本地化编写内部链接时不要带语言前缀通常也不带版本只写章节路径。两个插件会在构建期自动将链接本地化使每个页面都链接到自身语言与版本范围内的目标页。两个插件分别是src/plugins/remark-rewrite-localized-links.mjs —— 处理 Markdown 链接textsrc/plugins/rehype-rewrite-localized-links.mjs —— 处理原始 HTML/JSX 锚点a href/...例如包裹Card组件的链接卡片Markdown 链接语法无法表达这种场景两者共享 src/plugins/rewrite-localized-links-core.mjs 中的逻辑与默认值DEFAULT_PREFIXES为可本地化章节DEFAULT_VERSIONED_SECTIONS为携带版本的章节最新版本来自 src/config/versions.ts不带版本的 global 页面列表则从菜单自动派生。它们在 astro.config.mjs 的 markdown processor 中注册无需额外传参。链接写法对照表以西班牙语、5.x 页面中编写的链接为例你写的渲染为原因/api/express/es/5x/api/express/版本化章节 → 注入文件版本/guide/routing/es/5x/guide/routing/版本化文档页 → 注入文件版本/guide/migrating-5/es/guide/migrating-5/global 页面 → 无版本化 URL保持原样/4x/api/express/es/4x/api/express/显式版本被保留/resources/middleware/es/resources/middleware/resources永不携带版本链接编写规则始终省略语言。插件会自动给链接加上当前页面的语言前缀。永远不要写/en/...——因为翻译内容从 Crowdin 原样同步硬编码语言会让翻译后的页面错误地链接回英文页面。版本化章节api、starter、guide、advanced携带版本链接自身带版本则保留链接省略版本时注入源文件的版本docs/api集合或非版本化集合中的最新版本DEFAULT_VERSION。写/api/express或/guide/routing在 5.x 文件中都会解析为/…/5x/…。global 页面是例外少量guide/advanced页面位于不带版本的pages集合如migrating-5、best-practice-performance它们没有版本化 URL链接到它们时始终不带版本。此列表从菜单中标记global: true的条目自动派生位于 src/config/menu/无需手动维护。resources、support、blog永不携带版本链接仅带语言。不处理的情况外部 URL、相对链接./x、纯锚点#x以及已本地化的链接/en/...都原样保留。源码级实现细节核心插件rewriteUrl的处理流程见 src/plugins/rewrite-localized-links-core.mjs包括上下文推导deriveContextFromFile从源文件路径解析语言与版本。语言优先的集合docs、pages形如{lang}/[version]/...共享集合api版本优先、blog平铺没有语言段回退到默认语言en。版本判定isVersionSegment通过/^\dx$/正则识别5x、4x这类版本段。global 页列表collectGlobalPaths遍历 src/config/menu/docs.ts 中所有global: true菜单项收集其section/slug作为无版本化 URL的目标集合无需手动配置。URL 规整ensureTrailingSlash为非文件路径补全尾部斜杠splitPathAndSuffix负责分离查询串与哈希片段并原样保留。这些规则在 tests/unit/remark-rewrite-localized-links.test.mjs约 20 个用例与 tests/unit/rehype-rewrite-localized-links.test.mjs 中有完整验证覆盖跨版本链接保留、global 页面去版本化、显式版本丢弃、语言回退、查询串/哈希保留、引用式链接definition节点改写等场景。已本地化链接的渲染处理值得注意的一个细节api与blog属于共享集合src/content/api/ 与 src/content/blog/内容只编译一次其内部链接在编译时已固化为默认语言。因此 src/pages/[lang]/[...slug].astro 在渲染这些集合时会通过components{{ a: LocalizedLink }}注入 LocalizedLink 组件按当前渲染语言对链接做二次本地化。九、全站语言与 SEO 配置链接本地化依赖全站语言体系。语言列表定义在 src/i18n/locales.ts共支持 10 种语言en、de、es、fr、it、ja、ko、pt-br、zh-cn、zh-twUI 文案分别存放于 src/i18n/ui/ 下的各语言 JSON 文件。站点地图sitemap配置见 astro.config.mjs只收录带语言前缀的规范 URL并排除移动/删除页面的重定向占位。结语内容编写的核心要点综合官方指南与源码实现为 Express 官网编写内容时需牢记以下要点选对集合分版本指南放docsAPI 参考放api仅英文跨版本共享页面放pages并标记global: true博客文章放blog。Frontmatter 合规title必填、description可选MDX 文件把组件 import 放在 frontmatter 之后。善用 Code Tabs用cjs/mjs/ts方言或tab...标记连续代码块自动获得标签页与 import 注入。版本单一事实源新增版本只需改 src/config/versions.ts 一处另更新类型与菜单路由、侧边栏、链接插件全部自动跟随。链接只写路径不写语言让 remark/rehype 链接本地化插件 在构建期自动为每种语言、每个版本生成正确链接。这套体系保证了官网在 3 个 Express 版本、10 种语言之间的一致性作者只需关注内容本身版本与语言适配全部由构建管线自动完成。赞分享文档教程技术博客【免费下载链接】expressjs.comThe Express.js Website项目地址https://gitcode.com/gh_mirrors/ex/expressjs.com点击查看免费下载相关推荐Apache Pulsar 官网与文档开发全指南本地构建、Markdown 规范、版本化与多语言翻译Apache Pulsar 官网与文档开发全指南本地构建、Markdown 规范、版本化与多语言翻译 本篇技术指南以 Pulsar 仓库中的 site2/RE消息队列后端流处理Bull for Nest框架完全指南构建高效Node.js任务队列系统Bull for Nest框架完全指南构建高效Node.js任务队列系统 Bull是Nest框架的官方任务队列模块基于Redis构建专为Node.js应用消息队列后端OpenResume多语言SEOhreflang与本地化内容策略OpenResume多语言SEOhreflang与本地化内容策略 在全球化求职市场中一份能够跨越语言障碍的简历往往能为求职者赢得更多机会。OpenResum前端上一篇Steam创意工坊下载器WorkshopDL跨平台游戏模组自由获取指南下一篇网盘直链助手打破下载限制获取九大网盘真实下载链接的实用指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑