Skip to content

Commit

Permalink
feat: 页面数据流打通
Browse files Browse the repository at this point in the history
  • Loading branch information
c0dedance committed Oct 22, 2023
1 parent 83452c3 commit 8939c89
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 22 deletions.
6 changes: 3 additions & 3 deletions src/node/__test__/plugin-routes/RouteService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ describe('RouteService', async () => {
import Route1 from 'TEST_DIR/guide/a.tsx';
import Route2 from 'TEST_DIR/guide/index.tsx';
export const routes = [
{ \\"path\\": '/b', \\"element\\": React.createElement(Route0)},
{ \\"path\\": '/guide/a', \\"element\\": React.createElement(Route1)},
{ \\"path\\": '/guide/', \\"element\\": React.createElement(Route2)},
{ \\"path\\": '/b', \\"element\\": React.createElement(Route0), \\"preload\\": () => import('TEST_DIR/b.tsx')},
{ \\"path\\": '/guide/a', \\"element\\": React.createElement(Route1), \\"preload\\": () => import('TEST_DIR/guide/a.tsx')},
{ \\"path\\": '/guide/', \\"element\\": React.createElement(Route2), \\"preload\\": () => import('TEST_DIR/guide/index.tsx')},
]
"
`)
Expand Down
2 changes: 1 addition & 1 deletion src/node/plugin-routes/RouteService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export const routes = [
${this.#routeMeta
.map(
(item, index) =>
`{ "path": '${item.routePath}', "element": React.createElement(Route${index})},`
`{ "path": '${item.routePath}', "element": React.createElement(Route${index}), "preload": () => import('${item.absolutePath}')},`
)
.join('\n')}
]
Expand Down
3 changes: 2 additions & 1 deletion src/node/plugin-routes/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import { Plugin } from 'vite'
import { RouteService } from './RouteService'
import type { PageModule } from 'shared/types'

interface PluginOptions {
root: string
Expand All @@ -10,6 +10,7 @@ export interface Route {
path: string
element: React.ReactElement
filePath: string
preload: () => Promise<PageModule>
}

const CONVENTIONAL_ROUTE_ID = 'rpress:routes'
Expand Down
23 changes: 23 additions & 0 deletions src/runtime/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { matchRoutes } from 'react-router-dom'
import { Layout } from './theme-default'
import siteData from 'rpress:site-data'
import { routes } from 'rpress:routes'
import type { PageData } from 'shared/types'

export default function App() {
return (
Expand All @@ -7,3 +11,22 @@ export default function App() {
</>
)
}

export async function initPageData(routePath: string): Promise<PageData> {
const matched = matchRoutes(routes, routePath)
if (!matched) {
return {
siteData,
pagePath: routePath,
frontmatter: {},
pageType: '404',
}
}
const moduleInfo = await matched[0].route.preload()
return {
siteData,
pagePath: routePath,
frontmatter: moduleInfo.frontmatter,
pageType: 'doc',
}
}
17 changes: 12 additions & 5 deletions src/runtime/client-entry.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
import { createRoot } from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'
import App from './App'
import App, { initPageData } from './App'
import { DataContext } from './hooks'

function renderInBrowser() {
async function renderInBrowser() {
const containerEl = document.getElementById('root')
if (!containerEl) {
throw new Error('#root element not found')
}
// 初始化 PageData
const pageData = await initPageData(location.pathname)
console.log(pageData, 'pageData')

createRoot(containerEl).render(
<BrowserRouter>
<App />
</BrowserRouter>
<DataContext.Provider value={pageData}>
<BrowserRouter>
<App />
</BrowserRouter>
</DataContext.Provider>
)
}

Expand Down
9 changes: 9 additions & 0 deletions src/runtime/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { createContext, useContext } from 'react'
import type { PageData } from 'shared/types'

export const DataContext = createContext({} as PageData)

/* 提供数据供前端组件消费 */
export const usePageData = () => {
return useContext(DataContext)
}
2 changes: 2 additions & 0 deletions src/runtime/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { Content } from './Content'
export * from './hooks'
25 changes: 15 additions & 10 deletions src/runtime/theme-default/Layout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
import { Content } from '../../Content'
import { usePageData } from '../../'
import 'uno.css'

export function Layout() {
return (
<div>
<h1>nav</h1>
<aside font="bold">sidebar</aside>
<aside>
<Content />
</aside>
</div>
)
const pageData = usePageData()
// 获取 pageType
const { pageType } = pageData
// 根据 pageType 分发不同的页面内容
const getContent = () => {
if (pageType === 'home') {
return <div>Home 页面</div>
} else if (pageType === 'doc') {
return <div>正文页面</div>
} else {
return <div>404 页面</div>
}
}
return <div>{getContent()}</div>
}
31 changes: 31 additions & 0 deletions src/shared/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import type { UserConfig as ViteUserConfig } from 'vite'
import type { ComponentType } from 'react'

export interface PageModule {
default: ComponentType
frontmatter?: FrontMatter
[key: string]: unknown
}

// 用户配置的超集
export interface SiteConfig {
Expand Down Expand Up @@ -41,3 +48,27 @@ type SidebarItem = {
text: string
link: string
}
/* page */
export type PageType = 'home' | 'doc' | 'custom' | '404'

export interface Header {
id: string
text: string
depth: number
}
// 页面元信息
export interface FrontMatter {
title?: string
description?: string
pageType?: PageType
sidebar?: boolean
outline?: boolean
}

export interface PageData {
siteData: UserConfig
pagePath: string
frontmatter: FrontMatter
pageType: PageType
toc?: Header[]
}
4 changes: 2 additions & 2 deletions src/shared/types/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ declare module 'rpress:site-data' {
export default siteData
}
declare module 'rpress:routes' {
import type { RouteObject } from 'react-router-dom'
const routes: RouteObject[]
import type { Route } from 'node/plugin-routes'
const routes: Route[]
export { routes }
}

0 comments on commit 8939c89

Please sign in to comment.