From 3531666eb02b92f44fed451ee2d08ab3031d347f Mon Sep 17 00:00:00 2001 From: yangxiaolang <1810849666@qq.com> Date: Mon, 20 Apr 2026 23:47:25 +0800 Subject: [PATCH 1/3] chore: mod type module --- doom.config.ts | 15 ++++++++------ package.json | 1 + .../plugin-post-resolver/BlogPostResolver.ts | 8 ++++---- plugins/plugin-post-resolver/PostData.ts | 4 ++-- plugins/plugin-post-resolver/index.ts | 20 +++++++++---------- postcss.config.js | 12 +++++------ theme/components/HomeContent/index.tsx | 12 +++++------ theme/components/PostList/index.tsx | 8 ++++---- theme/components/SidebarMenu/index.ts | 2 +- theme/index.tsx | 10 +++++----- theme/layout/DocLayout/index.tsx | 14 ++++++------- theme/layout/HomeLayout/index.tsx | 6 +++--- theme/layout/index.tsx | 8 ++++---- 13 files changed, 62 insertions(+), 58 deletions(-) diff --git a/doom.config.ts b/doom.config.ts index 89d82682c..7d0a58aca 100644 --- a/doom.config.ts +++ b/doom.config.ts @@ -1,9 +1,12 @@ -import { defineConfig } from "@alauda/doom/config"; -import { join } from "node:path"; -import { blogPostResolver } from "./plugins/plugin-post-resolver"; - -export default defineConfig({ - title: "Alauda Knowledge", +import { defineConfig } from "@alauda/doom/config"; +import { dirname, join } from "node:path"; +import { fileURLToPath } from "node:url"; +import { blogPostResolver } from "./plugins/plugin-post-resolver/index.js"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); + +export default defineConfig({ + title: "Alauda Knowledge", base: "/knowledge/", description: "Welcome to Alauda's Knowledgebase information center. Find resources for resolving problems and troubleshooting.", diff --git a/package.json b/package.json index a9daf5e2b..49bbf24a4 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "name": "doomslayer", + "type": "module", "packageManager": "yarn@4.13.0", "devDependencies": { "@alauda/doom": "^1.20.0", diff --git a/plugins/plugin-post-resolver/BlogPostResolver.ts b/plugins/plugin-post-resolver/BlogPostResolver.ts index c806f2152..3eb454e70 100644 --- a/plugins/plugin-post-resolver/BlogPostResolver.ts +++ b/plugins/plugin-post-resolver/BlogPostResolver.ts @@ -1,6 +1,6 @@ import path from "node:path"; import fs, { PathLike } from "node:fs"; -import { RspressPlugin } from "@rspress/shared"; +import type { RspressPlugin } from "@rspress/shared"; import { addPost, getPostInfo, @@ -9,9 +9,9 @@ import { postProducts, resetPostInfo, sortPostInfos, -} from "./PostData"; -import { PluginOptions } from "./types"; -import { deDuplicate } from "./utils"; +} from "./PostData.js"; +import type { PluginOptions } from "./types.js"; +import { deDuplicate } from "./utils.js"; function traverseFolder( folderPath: PathLike, diff --git a/plugins/plugin-post-resolver/PostData.ts b/plugins/plugin-post-resolver/PostData.ts index 6a1bb459a..a515482a1 100644 --- a/plugins/plugin-post-resolver/PostData.ts +++ b/plugins/plugin-post-resolver/PostData.ts @@ -1,7 +1,7 @@ import path from "node:path"; import dayjs from "dayjs"; import grayMatter from "gray-matter"; -import { PostInfo } from "./types"; +import type { PostInfo } from "./types.js"; import { excerptFilter, extractTitle, @@ -9,7 +9,7 @@ import { getGitLastUpdatedTimeStamp, normalizeTags, transformTime, -} from "./utils"; +} from "./utils.js"; export const postInfos: PostInfo[] = []; export const postProducts: string[] = []; diff --git a/plugins/plugin-post-resolver/index.ts b/plugins/plugin-post-resolver/index.ts index ea2c686d5..3066183aa 100644 --- a/plugins/plugin-post-resolver/index.ts +++ b/plugins/plugin-post-resolver/index.ts @@ -1,13 +1,13 @@ -import { blogPostResolver } from './BlogPostResolver' -import { postInfos, postProducts, postKinds } from './PostData' -import dayjs from 'dayjs' -import utc from 'dayjs/plugin/utc' -import timezone from 'dayjs/plugin/timezone' +import { blogPostResolver } from "./BlogPostResolver.js"; +import { postInfos, postProducts, postKinds } from "./PostData.js"; +import dayjs from "dayjs"; +import utc from "dayjs/plugin/utc.js"; +import timezone from "dayjs/plugin/timezone.js"; -dayjs.extend(utc) -dayjs.extend(timezone) -dayjs.tz.setDefault('Asia/Shanghai') +dayjs.extend(utc); +dayjs.extend(timezone); +dayjs.tz.setDefault("Asia/Shanghai"); -export * from './types' +export * from "./types.js"; -export { blogPostResolver, postInfos, postProducts, postKinds } +export { blogPostResolver, postInfos, postProducts, postKinds }; diff --git a/postcss.config.js b/postcss.config.js index 5a71ab59d..f69c5d411 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,6 +1,6 @@ -module.exports = { - plugins: { - "@tailwindcss/postcss": {}, - autoprefixer: {}, - }, -}; +export default { + plugins: { + "@tailwindcss/postcss": {}, + autoprefixer: {}, + }, +}; diff --git a/theme/components/HomeContent/index.tsx b/theme/components/HomeContent/index.tsx index d72972c94..b11edee03 100644 --- a/theme/components/HomeContent/index.tsx +++ b/theme/components/HomeContent/index.tsx @@ -12,12 +12,12 @@ import { PRODUCTS_SESSION_KEY, usePersistSearchParams, useSessionStorage, -} from "../../hooks/SessionStorage"; -import { Card } from "../Card"; -import Checkbox from "../Checkbox"; -import Pagination from "../Pagination"; -import { PostList } from "../PostList"; -import Search from "../Search"; +} from "../../hooks/SessionStorage.js"; +import { Card } from "../Card/index.js"; +import Checkbox from "../Checkbox/index.js"; +import Pagination from "../Pagination/index.js"; +import { PostList } from "../PostList/index.js"; +import Search from "../Search/index.js"; import React from "react"; const SEARCHED_LIMIT = 1000; diff --git a/theme/components/PostList/index.tsx b/theme/components/PostList/index.tsx index fab757860..4d9a5d399 100644 --- a/theme/components/PostList/index.tsx +++ b/theme/components/PostList/index.tsx @@ -3,10 +3,10 @@ import { useI18n, usePageData } from "@rspress/core/runtime"; import { Badge } from "@rspress/core/theme-original"; import { FC, useMemo } from "react"; -import { PostInfo } from "../../../plugins/plugin-post-resolver"; -import { DocID } from "../DocID"; -import EmptyState from "../Empty"; -import { LinkCard } from "../LinkCard"; +import type { PostInfo } from "../../../plugins/plugin-post-resolver/types.js"; +import { DocID } from "../DocID/index.js"; +import EmptyState from "../Empty/index.js"; +import { LinkCard } from "../LinkCard/index.js"; interface PostListProps { postList: PostInfo[]; diff --git a/theme/components/SidebarMenu/index.ts b/theme/components/SidebarMenu/index.ts index aa25bad29..a55099f65 100644 --- a/theme/components/SidebarMenu/index.ts +++ b/theme/components/SidebarMenu/index.ts @@ -1,2 +1,2 @@ -export { useSidebarMenu } from './useSidebarMenu'; +export { useSidebarMenu } from "./useSidebarMenu.js"; diff --git a/theme/index.tsx b/theme/index.tsx index d96152773..85e9860b8 100644 --- a/theme/index.tsx +++ b/theme/index.tsx @@ -1,11 +1,11 @@ -import Layout from "./layout"; -import HomeLayout from "./layout/HomeLayout"; -import { DocLayout } from "./layout/DocLayout"; +import Layout from "./layout/index.js"; +import HomeLayout from "./layout/HomeLayout/index.js"; +import { DocLayout } from "./layout/DocLayout/index.js"; export { HomeLayout, Layout, DocLayout }; export * from "@rspress/core/theme-original"; // 导出本地实现的组件 -export { Card } from "./components/Card"; -export { LinkCard } from "./components/LinkCard"; +export { Card } from "./components/Card/index.js"; +export { LinkCard } from "./components/LinkCard/index.js"; diff --git a/theme/layout/DocLayout/index.tsx b/theme/layout/DocLayout/index.tsx index fafce408f..de829bf5d 100644 --- a/theme/layout/DocLayout/index.tsx +++ b/theme/layout/DocLayout/index.tsx @@ -1,14 +1,14 @@ import { useFrontmatter } from '@rspress/core/runtime'; -import { - DocContent, - DocFooter, +import { + DocContent, + DocFooter, Outline, Overview, useWatchToc, -} from '@rspress/core/theme-original'; -import clsx from 'clsx'; -import React from 'react'; -import { useSidebarMenu } from '../../components/SidebarMenu'; +} from '@rspress/core/theme-original'; +import clsx from 'clsx'; +import React from 'react'; +import { useSidebarMenu } from '../../components/SidebarMenu/index.js'; export interface DocLayoutProps { beforeSidebar?: React.ReactNode; diff --git a/theme/layout/HomeLayout/index.tsx b/theme/layout/HomeLayout/index.tsx index 07559b4fe..912ea2c2d 100644 --- a/theme/layout/HomeLayout/index.tsx +++ b/theme/layout/HomeLayout/index.tsx @@ -1,9 +1,9 @@ import { usePageData } from "@rspress/core/runtime"; import { ReactNode } from "react"; -import { HomeBanner } from "../../components/HomeBanner"; -import { HomeContent } from "../../components/HomeContent"; -import React from "react"; +import { HomeBanner } from "../../components/HomeBanner/index.js"; +import { HomeContent } from "../../components/HomeContent/index.js"; +import React from "react"; const HomeLayout: React.FC<{ children: ReactNode }> = ({ children }) => { return ( diff --git a/theme/layout/index.tsx b/theme/layout/index.tsx index fe5688367..bbef9ca0a 100644 --- a/theme/layout/index.tsx +++ b/theme/layout/index.tsx @@ -7,10 +7,10 @@ import { } from "@rspress/core/theme-original"; import { useEffect } from "react"; -import { BreadCrumb } from "../components/BreadCrumb"; -import { DocID } from "../components/DocID"; -import { EditOnGithub } from "../components/EditOnGithub"; -import HomeLayout from "./HomeLayout"; +import { BreadCrumb } from "../components/BreadCrumb/index.js"; +import { DocID } from "../components/DocID/index.js"; +import { EditOnGithub } from "../components/EditOnGithub/index.js"; +import HomeLayout from "./HomeLayout/index.js"; import { getPathname, shouldDownload } from "theme/utils/download"; export function normalizeTags(tags: string | string[]): string[] { From 33a8e19b4d49552e03eea91db77c2b3c153c99be Mon Sep 17 00:00:00 2001 From: yangxiaolang <1810849666@qq.com> Date: Fri, 15 May 2026 15:12:45 +0800 Subject: [PATCH 2/3] feat: resolve knowledge articles by id --- theme/layout/index.tsx | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/theme/layout/index.tsx b/theme/layout/index.tsx index bbef9ca0a..d101a13a7 100644 --- a/theme/layout/index.tsx +++ b/theme/layout/index.tsx @@ -6,6 +6,7 @@ import { getCustomMDXComponent, } from "@rspress/core/theme-original"; import { useEffect } from "react"; +import { postInfos } from "virtual-post-data"; import { BreadCrumb } from "../components/BreadCrumb/index.js"; import { DocID } from "../components/DocID/index.js"; @@ -46,9 +47,45 @@ const Badges = () => { }; export default () => { + const { page } = usePageData(); + useEffect(() => { + if (typeof window === "undefined") { + return; + } + + const currentUrl = new URL(window.location.href); + const postId = currentUrl.searchParams.get("id")?.trim(); + + if (postId) { + const matchedPost = + postInfos.find( + (post) => post.id === postId && post.locale === page.lang + ) || postInfos.find((post) => post.id === postId); + + if (matchedPost) { + const nextUrl = new URL( + withBase( + matchedPost.route.endsWith(".html") + ? matchedPost.route + : `${matchedPost.route}.html` + ), + currentUrl.origin + ); + + currentUrl.searchParams.delete("id"); + nextUrl.search = currentUrl.searchParams.toString(); + nextUrl.hash = currentUrl.hash; + + if (nextUrl.toString() !== currentUrl.toString()) { + window.location.replace(nextUrl.toString()); + return; + } + } + } + window.parent.postMessage(window.location.href, "*"); - }, []); + }, [page.lang]); return ( Date: Fri, 15 May 2026 16:53:56 +0800 Subject: [PATCH 3/3] fix: resolve knowledge article ids from initial url --- theme/layout/index.tsx | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/theme/layout/index.tsx b/theme/layout/index.tsx index d101a13a7..92f1a252f 100644 --- a/theme/layout/index.tsx +++ b/theme/layout/index.tsx @@ -24,6 +24,16 @@ export function normalizeTags(tags: string | string[]): string[] { return [tags]; } +function normalizePostId(id?: string): string { + return id?.trim().toLowerCase() || ""; +} + +const initialHref = typeof window === "undefined" ? "" : window.location.href; + +function getInitialHref(): string { + return initialHref || window.location.href; +} + const Badges = () => { const { page } = usePageData(); const kinds = normalizeTags( @@ -54,14 +64,20 @@ export default () => { return; } - const currentUrl = new URL(window.location.href); + const currentUrl = new URL(getInitialHref()); const postId = currentUrl.searchParams.get("id")?.trim(); + const normalizedPostId = normalizePostId(postId); - if (postId) { + if (normalizedPostId) { const matchedPost = postInfos.find( - (post) => post.id === postId && post.locale === page.lang - ) || postInfos.find((post) => post.id === postId); + (post) => + normalizePostId(post.id) === normalizedPostId && + post.locale === page.lang + ) || + postInfos.find( + (post) => normalizePostId(post.id) === normalizedPostId + ); if (matchedPost) { const nextUrl = new URL(