From 0a3aad618eb79415427a895e1aadef0373ae52ca Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Fri, 8 Apr 2022 00:38:33 +0800 Subject: [PATCH] feat(core): allow plugins to declare custom route context (#7082) --- packages/docusaurus-types/src/index.d.ts | 6 ++++++ .../__snapshots__/routes.test.ts.snap | 19 +++++++++++++------ .../src/server/__tests__/routes.test.ts | 6 ++++++ .../docusaurus/src/server/plugins/index.ts | 17 +++++++---------- packages/docusaurus/src/server/routes.ts | 4 ++++ 5 files changed, 36 insertions(+), 16 deletions(-) diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index fcfdb35e18..e20bd74ee6 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -493,6 +493,12 @@ export type RouteConfig = { * `createData`) */ modules?: RouteModules; + /** + * The route context will wrap the `component`. Use `useRouteContext` to + * retrieve what's declared here. Note that all custom route context declared + * here will be namespaced under {@link RouteContext.data}. + */ + context?: RouteModules; /** Nested routes config. */ routes?: RouteConfig[]; /** React router config option: `exact` routes would not match subroutes. */ diff --git a/packages/docusaurus/src/server/__tests__/__snapshots__/routes.test.ts.snap b/packages/docusaurus/src/server/__tests__/__snapshots__/routes.test.ts.snap index 80de4e006f..9979705a31 100644 --- a/packages/docusaurus/src/server/__tests__/__snapshots__/routes.test.ts.snap +++ b/packages/docusaurus/src/server/__tests__/__snapshots__/routes.test.ts.snap @@ -66,19 +66,26 @@ exports[`loadRoutes loads nested route config 1`] = ` "docsMetadata---docs-routef-34-881": "docs-b5f.json", "metadata---docs-foo-baz-2-cf-fa7": "docs-foo-baz-dd9.json", "metadata---docs-hello-956-741": "docs-hello-da2.json", + "plugin---docs-hello-665-3ca": "pluginRouteContextModule-100.json", }, "routesChunkNames": { - "/docs/hello-44b": { + "/docs/hello-fcc": { "__comp": "__comp---theme-doc-item-178-a40", + "__context": { + "plugin": "plugin---docs-hello-665-3ca", + }, "content": "content---docs-helloaff-811", "metadata": "metadata---docs-hello-956-741", }, - "/docs:route-52d": { + "/docs:route-502": { "__comp": "__comp---theme-doc-page-1-be-9be", "docsMetadata": "docsMetadata---docs-routef-34-881", }, - "docs/foo/baz-070": { + "docs/foo/baz-eb2": { "__comp": "__comp---theme-doc-item-178-a40", + "__context": { + "plugin": "plugin---docs-hello-665-3ca", + }, "content": "content---docs-foo-baz-8-ce-61e", "metadata": "metadata---docs-foo-baz-2-cf-fa7", }, @@ -89,17 +96,17 @@ import ComponentCreator from '@docusaurus/ComponentCreator'; export default [ { path: '/docs:route', - component: ComponentCreator('/docs:route', '52d'), + component: ComponentCreator('/docs:route', '502'), routes: [ { path: '/docs/hello', - component: ComponentCreator('/docs/hello', '44b'), + component: ComponentCreator('/docs/hello', 'fcc'), exact: true, sidebar: \\"main\\" }, { path: 'docs/foo/baz', - component: ComponentCreator('docs/foo/baz', '070'), + component: ComponentCreator('docs/foo/baz', 'eb2'), sidebar: \\"secondary\\", \\"key:a\\": \\"containing colon\\", \\"key'b\\": \\"containing quote\\", diff --git a/packages/docusaurus/src/server/__tests__/routes.test.ts b/packages/docusaurus/src/server/__tests__/routes.test.ts index 1e8062a696..b18f0ccca6 100644 --- a/packages/docusaurus/src/server/__tests__/routes.test.ts +++ b/packages/docusaurus/src/server/__tests__/routes.test.ts @@ -117,6 +117,9 @@ describe('loadRoutes', () => { content: 'docs/hello.md', metadata: 'docs-hello-da2.json', }, + context: { + plugin: 'pluginRouteContextModule-100.json', + }, sidebar: 'main', }, { @@ -126,6 +129,9 @@ describe('loadRoutes', () => { content: 'docs/foo/baz.md', metadata: 'docs-foo-baz-dd9.json', }, + context: { + plugin: 'pluginRouteContextModule-100.json', + }, sidebar: 'secondary', 'key:a': 'containing colon', "key'b": 'containing quote', diff --git a/packages/docusaurus/src/server/plugins/index.ts b/packages/docusaurus/src/server/plugins/index.ts index d63b95589b..c87c99dc9e 100644 --- a/packages/docusaurus/src/server/plugins/index.ts +++ b/packages/docusaurus/src/server/plugins/index.ts @@ -104,22 +104,19 @@ export async function loadPlugins(context: LoadContext): Promise<{ plugin.name, pluginId, ); - // TODO this would be better to do all that in the codegen phase - // TODO handle context for nested routes - const pluginRouteContext: PluginRouteContext = { - plugin: {name: plugin.name, id: pluginId}, - data: undefined, // TODO allow plugins to provide context data - }; const pluginRouteContextModulePath = path.join( dataDir, `${docuHash('pluginRouteContextModule')}.json`, ); + const pluginRouteContext: PluginRouteContext['plugin'] = { + name: plugin.name, + id: pluginId, + }; await generate( '/', pluginRouteContextModulePath, JSON.stringify(pluginRouteContext, null, 2), ); - const actions: PluginContentLoadedActions = { addRoute(initialRouteConfig) { // Trailing slash behavior is handled generically for all plugins @@ -129,9 +126,9 @@ export async function loadPlugins(context: LoadContext): Promise<{ ); pluginsRouteConfigs.push({ ...finalRouteConfig, - modules: { - ...finalRouteConfig.modules, - __context: pluginRouteContextModulePath, + context: { + ...(finalRouteConfig.context && {data: finalRouteConfig.context}), + plugin: pluginRouteContextModulePath, }, }); }, diff --git a/packages/docusaurus/src/server/routes.ts b/packages/docusaurus/src/server/routes.ts index 6350e21660..733bf0bc2f 100644 --- a/packages/docusaurus/src/server/routes.ts +++ b/packages/docusaurus/src/server/routes.ts @@ -250,6 +250,7 @@ function genRouteCode(routeConfig: RouteConfig, res: LoadedRoutes): string { path: routePath, component, modules = {}, + context, routes: subroutes, priority, exact, @@ -271,6 +272,9 @@ ${JSON.stringify(routeConfig)}`, res.routesChunkNames[`${routePath}-${routeHash}`] = { // Avoid clash with a prop called "component" ...genChunkNames({__comp: component}, 'component', component, res), + ...(context + ? genChunkNames({__context: context}, 'context', routePath, res) + : {}), ...genChunkNames(modules, 'module', routePath, res), };