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`)
*/
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. */

View file

@ -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\\",

View file

@ -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',

View file

@ -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,
},
});
},

View file

@ -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),
};