Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(v2): allow using classic theme/preset without the docs plugin #3382 #3384

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ packages/docusaurus-plugin-ideal-image/lib/
packages/docusaurus-theme-classic/lib/
packages/docusaurus-migrate/lib/

website/netlifyDeploy
website/netlifyDeployPreview

website-1.x-migrated
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@
"start:v2:watch": "nodemon --watch \"./packages/*/lib/**/*.*\" --exec \"yarn start:v2\"",
"start:v2:baseUrl": "yarn workspace docusaurus-2-website start:baseUrl",
"start:v2:bootstrap": "yarn workspace docusaurus-2-website start:bootstrap",
"start:v2:blogOnly": "yarn workspace docusaurus-2-website start:blogOnly",
"build": "yarn build:packages && yarn build:v2",
"build:packages": "lerna run build --no-private",
"build:v1": "yarn workspace docusaurus-1-website build",
"build:v2": "yarn workspace docusaurus-2-website build",
"build:v2:baseUrl": "yarn workspace docusaurus-2-website build:baseUrl",
"build:v2:blogOnly": "yarn workspace docusaurus-2-website build:blogOnly",
"serve:v1": "serve website-1.x/build/docusaurus",
"serve:v2": "serve website/build",
"serve:v2:baseUrl": "serve website",
Expand Down
1 change: 1 addition & 0 deletions packages/docusaurus-plugin-client-redirects/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@docusaurus/core": "^2.0.0-alpha.62",
"@docusaurus/types": "^2.0.0-alpha.62",
"@docusaurus/utils": "^2.0.0-alpha.62",
"@docusaurus/utils-validation": "^2.0.0-alpha.62",
"@hapi/joi": "^17.1.1",
"@types/hapi__joi": "^17.1.2",
"chalk": "^3.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import {PluginOptions, RedirectOption, UserPluginOptions} from './types';
import * as Joi from '@hapi/joi';
import {PathnameValidator} from './redirectValidation';
import {PathnameSchema} from '@docusaurus/utils-validation';
import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants';

export const DefaultPluginOptions: PluginOptions = {
Expand All @@ -18,10 +18,10 @@ export const DefaultPluginOptions: PluginOptions = {
};

const RedirectPluginOptionValidation = Joi.object<RedirectOption>({
to: PathnameValidator.required(),
to: PathnameSchema.required(),
from: Joi.alternatives().try(
PathnameValidator.required(),
Joi.array().items(PathnameValidator.required()),
PathnameSchema.required(),
Joi.array().items(PathnameSchema.required()),
),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,12 @@
*/

import * as Joi from '@hapi/joi';
import {isValidPathname} from '@docusaurus/utils';
import {RedirectMetadata} from './types';

export const PathnameValidator = Joi.string()
.custom((val) => {
if (!isValidPathname(val)) {
throw new Error();
} else {
return val;
}
})
.message(
'{{#label}} is not a valid pathname. Pathname should start with / and not contain any domain or query string',
);
import {PathnameSchema} from '@docusaurus/utils-validation';

const RedirectSchema = Joi.object<RedirectMetadata>({
from: PathnameValidator.required(),
to: PathnameValidator.required(),
from: PathnameSchema.required(),
to: PathnameSchema.required(),
});

export function validateRedirect(redirect: RedirectMetadata): void {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ test('should accept correctly defined user options', () => {
...DEFAULT_OPTIONS,
feedOptions: {type: 'rss', title: 'myTitle'},
path: 'not_blog',
routeBasePath: '',
routeBasePath: 'myBlog',
postsPerPage: 5,
include: ['api/*', 'docs/*'],
};
Expand All @@ -37,7 +37,7 @@ test('should accept correctly defined user options', () => {
test('should accept valid user options', async () => {
const userOptions = {
...DEFAULT_OPTIONS,
routeBasePath: '',
routeBasePath: 'myBlog',
beforeDefaultRemarkPlugins: [],
beforeDefaultRehypePlugins: [markdownPluginsFunctionStub],
remarkPlugins: [[markdownPluginsFunctionStub, {option1: '42'}]],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ export const DEFAULT_OPTIONS = {

export const PluginOptionSchema = Joi.object({
path: Joi.string().default(DEFAULT_OPTIONS.path),
routeBasePath: Joi.string().allow('').default(DEFAULT_OPTIONS.routeBasePath),
routeBasePath: Joi.string()
// '' not allowed, see https://github.com/facebook/docusaurus/issues/3374
// .allow('')
.default(DEFAULT_OPTIONS.routeBasePath),
include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include),
postsPerPage: Joi.number()
.integer()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,13 @@ describe('loadSidebars', () => {
});

test('unexisting path', () => {
/*
expect(() => loadSidebars('badpath')).toThrowErrorMatchingInlineSnapshot(
`"No sidebar file exist at path: badpath"`,
);
*/
// See https://github.com/facebook/docusaurus/issues/3366
expect(loadSidebars('badpath')).toEqual({});
});

test('undefined path', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,17 @@ describe('docsClientUtils', () => {
expect(getActivePlugin(data, '/')).toEqual(undefined);
expect(getActivePlugin(data, '/xyz')).toEqual(undefined);

expect(() =>
getActivePlugin(data, '/', {failfast: true}),
).toThrowErrorMatchingInlineSnapshot(
`"Can't find active docs plugin for pathname=/, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: /ios, /android"`,
);
expect(() =>
getActivePlugin(data, '/xyz', {failfast: true}),
).toThrowErrorMatchingInlineSnapshot(
`"Can't find active docs plugin for pathname=/xyz, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: /ios, /android"`,
);

const activePluginIos: ActivePlugin = {
pluginId: 'pluginIosId',
pluginData: data.pluginIosId,
Expand Down Expand Up @@ -115,6 +126,9 @@ describe('docsClientUtils', () => {
},
],
};

expect(getActiveVersion(data, '/someUnknownPath')).toEqual(undefined);

expect(getActiveVersion(data, '/docs/next')?.name).toEqual('next');
expect(getActiveVersion(data, '/docs/next/')?.name).toEqual('next');
expect(getActiveVersion(data, '/docs/next/someDoc')?.name).toEqual('next');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,27 @@ export type ActivePlugin = {
pluginData: GlobalPluginData;
};

export type GetActivePluginOptions = {failfast?: boolean};

// get the data of the plugin that is currently "active"
// ie the docs of that plugin are currently browsed
// it is useful to support multiple docs plugin instances
export const getActivePlugin = (
export function getActivePlugin(
allPluginDatas: Record<string, GlobalPluginData>,
pathname: string,
options: {failfast: true}, // use fail-fast option if you know for sure one plugin instance is active
): ActivePlugin;
export function getActivePlugin(
allPluginDatas: Record<string, GlobalPluginData>,
pathname: string,
options?: GetActivePluginOptions,
): ActivePlugin | undefined;

export function getActivePlugin(
allPluginDatas: Record<string, GlobalPluginData>,
pathname: string,
): ActivePlugin | undefined => {
options: GetActivePluginOptions = {},
): ActivePlugin | undefined {
const activeEntry = Object.entries(allPluginDatas).find(
([_id, pluginData]) => {
return !!matchPath(pathname, {
Expand All @@ -37,10 +51,22 @@ export const getActivePlugin = (
},
);

return activeEntry
const activePlugin: ActivePlugin | undefined = activeEntry
? {pluginId: activeEntry[0], pluginData: activeEntry[1]}
: undefined;
};

if (!activePlugin && options.failfast) {
throw new Error(
`Can't find active docs plugin for pathname=${pathname}, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(
allPluginDatas,
)
.map((plugin) => plugin.path)
.join(', ')}`,
);
}

return activePlugin;
}

export type ActiveDocContext = {
activeVersion?: Version;
Expand Down
5 changes: 4 additions & 1 deletion packages/docusaurus-plugin-content-docs/src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ const VersionsOptionsSchema = Joi.object()
export const OptionsSchema = Joi.object({
path: Joi.string().default(DEFAULT_OPTIONS.path),
editUrl: URISchema,
routeBasePath: Joi.string().allow('').default(DEFAULT_OPTIONS.routeBasePath),
routeBasePath: Joi.string()
// '' not allowed, see https://github.com/facebook/docusaurus/issues/3374
// .allow('') ""
.default(DEFAULT_OPTIONS.routeBasePath),
homePageId: Joi.string().optional(),
include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include),
sidebarPath: Joi.string().allow('').default(DEFAULT_OPTIONS.sidebarPath),
Expand Down
7 changes: 6 additions & 1 deletion packages/docusaurus-plugin-content-docs/src/sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,14 @@ export function loadSidebars(sidebarFilePath: string): Sidebars {
if (!sidebarFilePath) {
throw new Error(`sidebarFilePath not provided: ${sidebarFilePath}`);
}

// sidebars file is optional, some users use docs without sidebars!
// See https://github.com/facebook/docusaurus/issues/3366
if (!fs.existsSync(sidebarFilePath)) {
throw new Error(`No sidebar file exist at path: ${sidebarFilePath}`);
// throw new Error(`No sidebar file exist at path: ${sidebarFilePath}`);
return {};
}

// We don't want sidebars to be cached because of hot reloading.
const sidebarJson = importFresh(sidebarFilePath) as SidebarsJSON;
return normalizeSidebars(sidebarJson);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
getActiveVersion,
getActiveDocContext,
getDocVersionSuggestions,
GetActivePluginOptions,
} from '../../client/docsClientUtils';

const useAllDocsData = (): Record<string, GlobalPluginData> =>
Expand All @@ -26,10 +27,10 @@ const useAllDocsData = (): Record<string, GlobalPluginData> =>
const useDocsData = (pluginId: string | undefined) =>
usePluginData('docusaurus-plugin-content-docs', pluginId) as GlobalPluginData;

export const useActivePlugin = () => {
export const useActivePlugin = (options: GetActivePluginOptions = {}) => {
const data = useAllDocsData();
const {pathname} = useLocation();
return getActivePlugin(data, pathname);
return getActivePlugin(data, pathname, options);
};

// versions are returned ordered (most recent first)
Expand Down
9 changes: 7 additions & 2 deletions packages/docusaurus-plugin-content-docs/src/versions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {DEFAULT_PLUGIN_ID} from '@docusaurus/core/lib/constants';
import {LoadContext} from '@docusaurus/types';
import {normalizeUrl} from '@docusaurus/utils';
import {difference} from 'lodash';
import chalk from 'chalk';

// retro-compatibility: no prefix for the default plugin id
function addPluginIdPrefix(fileOrDir: string, pluginId: string): string {
Expand Down Expand Up @@ -222,9 +223,13 @@ function checkVersionMetadataPaths({
`The docs folder does not exist for version [${versionName}]. A docs folder is expected to be found at ${docsDirPath}`,
);
}

// See https://github.com/facebook/docusaurus/issues/3366
if (!fs.existsSync(sidebarFilePath)) {
throw new Error(
`The sidebar file does not exist for version [${versionName}]. A sidebar file is expected to be found at ${sidebarFilePath}`,
console.log(
chalk.yellow(
`The sidebar file of docs version [${versionName}] does not exist. It is optional, but should rather be provided at ${sidebarFilePath}`,
),
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {

export const DEFAULT_OPTIONS: PluginOptions = {
path: 'src/pages', // Path to data on filesystem, relative to site dir.
routeBasePath: '', // URL Route.
routeBasePath: '/', // URL Route.
include: ['**/*.{js,jsx,ts,tsx,md,mdx}'], // Extensions to include.
mdxPageComponent: '@theme/MDXPage',
remarkPlugins: [],
Expand Down
18 changes: 15 additions & 3 deletions packages/docusaurus-preset-bootstrap/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,21 @@ module.exports = function preset(context, opts = {}) {
return {
themes: [[require.resolve('@docusaurus/theme-bootstrap'), opts.theme]],
plugins: [
[require.resolve('@docusaurus/plugin-content-pages'), opts.pages],
[require.resolve('@docusaurus/plugin-content-blog'), opts.blog],
[require.resolve('@docusaurus/plugin-content-docs'), opts.docs],
[
opts.pages !== false &&
require.resolve('@docusaurus/plugin-content-pages'),
opts.pages,
],
[
opts.blog !== false &&
require.resolve('@docusaurus/plugin-content-blog'),
opts.blog,
],
[
opts.docs !== false &&
require.resolve('@docusaurus/plugin-content-docs'),
opts.docs,
],
],
};
};
21 changes: 17 additions & 4 deletions packages/docusaurus-preset-classic/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,28 @@ module.exports = function preset(context, opts = {}) {
algolia && require.resolve('@docusaurus/theme-search-algolia'),
],
plugins: [
[require.resolve('@docusaurus/plugin-content-docs'), opts.docs],
[require.resolve('@docusaurus/plugin-content-blog'), opts.blog],
[require.resolve('@docusaurus/plugin-content-pages'), opts.pages],
opts.docs !== false && [
require.resolve('@docusaurus/plugin-content-docs'),
opts.docs,
],
opts.blog !== false && [
require.resolve('@docusaurus/plugin-content-blog'),
opts.blog,
],
opts.pages !== false && [
require.resolve('@docusaurus/plugin-content-pages'),
opts.pages,
],
isProd &&
googleAnalytics &&
require.resolve('@docusaurus/plugin-google-analytics'),
debug && require.resolve('@docusaurus/plugin-debug'),
isProd && gtag && require.resolve('@docusaurus/plugin-google-gtag'),
isProd && [require.resolve('@docusaurus/plugin-sitemap'), opts.sitemap],
isProd &&
opts.sitemap !== false && [
require.resolve('@docusaurus/plugin-sitemap'),
opts.sitemap,
],
],
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ describe('themeConfig', () => {
{
type: 'docsVersionDropdown',
position: 'left',
nextVersionLabel: '2.0.0-next',
},
{
to: 'docs/next/support',
Expand Down
7 changes: 7 additions & 0 deletions packages/docusaurus-theme-classic/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ module.exports = function (context, options) {
.join('|');

return {
stats: {
warningsFilter: [
// See https://github.com/facebook/docusaurus/pull/3382
(warning) =>
warning.includes("Can't resolve '@theme-init/hooks/useDocs"),
],
},
plugins: [
new ContextReplacementPlugin(
/prismjs[\\/]components$/,
Expand Down
Loading