feat(core): allow plugins to declare custom route context (#7082)

This commit is contained in:
Joshua Chen 2022-04-08 00:38:33 +08:00 committed by GitHub
parent 1156be3f20
commit 0a3aad618e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 16 deletions

View file

@ -493,6 +493,12 @@ export type RouteConfig = {
* `createData`) * `createData`)
*/ */
modules?: RouteModules; 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. */ /** Nested routes config. */
routes?: RouteConfig[]; routes?: RouteConfig[];
/** React router config option: `exact` routes would not match subroutes. */ /** React router config option: `exact` routes would not match subroutes. */

View file

@ -66,19 +66,26 @@ exports[`loadRoutes loads nested route config 1`] = `
"docsMetadata---docs-routef-34-881": "docs-b5f.json", "docsMetadata---docs-routef-34-881": "docs-b5f.json",
"metadata---docs-foo-baz-2-cf-fa7": "docs-foo-baz-dd9.json", "metadata---docs-foo-baz-2-cf-fa7": "docs-foo-baz-dd9.json",
"metadata---docs-hello-956-741": "docs-hello-da2.json", "metadata---docs-hello-956-741": "docs-hello-da2.json",
"plugin---docs-hello-665-3ca": "pluginRouteContextModule-100.json",
}, },
"routesChunkNames": { "routesChunkNames": {
"/docs/hello-44b": { "/docs/hello-fcc": {
"__comp": "__comp---theme-doc-item-178-a40", "__comp": "__comp---theme-doc-item-178-a40",
"__context": {
"plugin": "plugin---docs-hello-665-3ca",
},
"content": "content---docs-helloaff-811", "content": "content---docs-helloaff-811",
"metadata": "metadata---docs-hello-956-741", "metadata": "metadata---docs-hello-956-741",
}, },
"/docs:route-52d": { "/docs:route-502": {
"__comp": "__comp---theme-doc-page-1-be-9be", "__comp": "__comp---theme-doc-page-1-be-9be",
"docsMetadata": "docsMetadata---docs-routef-34-881", "docsMetadata": "docsMetadata---docs-routef-34-881",
}, },
"docs/foo/baz-070": { "docs/foo/baz-eb2": {
"__comp": "__comp---theme-doc-item-178-a40", "__comp": "__comp---theme-doc-item-178-a40",
"__context": {
"plugin": "plugin---docs-hello-665-3ca",
},
"content": "content---docs-foo-baz-8-ce-61e", "content": "content---docs-foo-baz-8-ce-61e",
"metadata": "metadata---docs-foo-baz-2-cf-fa7", "metadata": "metadata---docs-foo-baz-2-cf-fa7",
}, },
@ -89,17 +96,17 @@ import ComponentCreator from '@docusaurus/ComponentCreator';
export default [ export default [
{ {
path: '/docs:route', path: '/docs:route',
component: ComponentCreator('/docs:route', '52d'), component: ComponentCreator('/docs:route', '502'),
routes: [ routes: [
{ {
path: '/docs/hello', path: '/docs/hello',
component: ComponentCreator('/docs/hello', '44b'), component: ComponentCreator('/docs/hello', 'fcc'),
exact: true, exact: true,
sidebar: \\"main\\" sidebar: \\"main\\"
}, },
{ {
path: 'docs/foo/baz', path: 'docs/foo/baz',
component: ComponentCreator('docs/foo/baz', '070'), component: ComponentCreator('docs/foo/baz', 'eb2'),
sidebar: \\"secondary\\", sidebar: \\"secondary\\",
\\"key:a\\": \\"containing colon\\", \\"key:a\\": \\"containing colon\\",
\\"key'b\\": \\"containing quote\\", \\"key'b\\": \\"containing quote\\",

View file

@ -117,6 +117,9 @@ describe('loadRoutes', () => {
content: 'docs/hello.md', content: 'docs/hello.md',
metadata: 'docs-hello-da2.json', metadata: 'docs-hello-da2.json',
}, },
context: {
plugin: 'pluginRouteContextModule-100.json',
},
sidebar: 'main', sidebar: 'main',
}, },
{ {
@ -126,6 +129,9 @@ describe('loadRoutes', () => {
content: 'docs/foo/baz.md', content: 'docs/foo/baz.md',
metadata: 'docs-foo-baz-dd9.json', metadata: 'docs-foo-baz-dd9.json',
}, },
context: {
plugin: 'pluginRouteContextModule-100.json',
},
sidebar: 'secondary', sidebar: 'secondary',
'key:a': 'containing colon', 'key:a': 'containing colon',
"key'b": 'containing quote', "key'b": 'containing quote',

View file

@ -104,22 +104,19 @@ export async function loadPlugins(context: LoadContext): Promise<{
plugin.name, plugin.name,
pluginId, 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( const pluginRouteContextModulePath = path.join(
dataDir, dataDir,
`${docuHash('pluginRouteContextModule')}.json`, `${docuHash('pluginRouteContextModule')}.json`,
); );
const pluginRouteContext: PluginRouteContext['plugin'] = {
name: plugin.name,
id: pluginId,
};
await generate( await generate(
'/', '/',
pluginRouteContextModulePath, pluginRouteContextModulePath,
JSON.stringify(pluginRouteContext, null, 2), JSON.stringify(pluginRouteContext, null, 2),
); );
const actions: PluginContentLoadedActions = { const actions: PluginContentLoadedActions = {
addRoute(initialRouteConfig) { addRoute(initialRouteConfig) {
// Trailing slash behavior is handled generically for all plugins // Trailing slash behavior is handled generically for all plugins
@ -129,9 +126,9 @@ export async function loadPlugins(context: LoadContext): Promise<{
); );
pluginsRouteConfigs.push({ pluginsRouteConfigs.push({
...finalRouteConfig, ...finalRouteConfig,
modules: { context: {
...finalRouteConfig.modules, ...(finalRouteConfig.context && {data: finalRouteConfig.context}),
__context: pluginRouteContextModulePath, plugin: pluginRouteContextModulePath,
}, },
}); });
}, },

View file

@ -250,6 +250,7 @@ function genRouteCode(routeConfig: RouteConfig, res: LoadedRoutes): string {
path: routePath, path: routePath,
component, component,
modules = {}, modules = {},
context,
routes: subroutes, routes: subroutes,
priority, priority,
exact, exact,
@ -271,6 +272,9 @@ ${JSON.stringify(routeConfig)}`,
res.routesChunkNames[`${routePath}-${routeHash}`] = { res.routesChunkNames[`${routePath}-${routeHash}`] = {
// Avoid clash with a prop called "component" // Avoid clash with a prop called "component"
...genChunkNames({__comp: component}, 'component', component, res), ...genChunkNames({__comp: component}, 'component', component, res),
...(context
? genChunkNames({__context: context}, 'context', routePath, res)
: {}),
...genChunkNames(modules, 'module', routePath, res), ...genChunkNames(modules, 'module', routePath, res),
}; };