Skip to content

Commit 21ab58d

Browse files
slorberOzakIOne
authored andcommitted
feat(core): allow plugins to self-disable by returning null (#10286)
1 parent b32a990 commit 21ab58d

File tree

13 files changed

+184
-89
lines changed

13 files changed

+184
-89
lines changed

packages/docusaurus-plugin-client-redirects/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ const PluginName = 'docusaurus-plugin-client-redirects';
2121
export default function pluginClientRedirectsPages(
2222
context: LoadContext,
2323
options: PluginOptions,
24-
): Plugin<void> {
24+
): Plugin<void> | null {
2525
const {trailingSlash} = context.siteConfig;
2626
const router = context.siteConfig.future.experimental_router;
2727

2828
if (router === 'hash') {
2929
logger.warn(
3030
`${PluginName} does not support the Hash Router and will be disabled.`,
3131
);
32-
return {name: PluginName};
32+
return null;
3333
}
3434

3535
return {

packages/docusaurus-plugin-google-analytics/src/index.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,21 @@ import type {PluginOptions, Options} from './options';
1818
export default function pluginGoogleAnalytics(
1919
context: LoadContext,
2020
options: PluginOptions,
21-
): Plugin {
21+
): Plugin | null {
22+
if (process.env.NODE_ENV !== 'production') {
23+
return null;
24+
}
25+
2226
const {trackingID, anonymizeIP} = options;
23-
const isProd = process.env.NODE_ENV === 'production';
2427

2528
return {
2629
name: 'docusaurus-plugin-google-analytics',
2730

2831
getClientModules() {
29-
return isProd ? ['./analytics'] : [];
32+
return ['./analytics'];
3033
},
3134

3235
injectHtmlTags() {
33-
if (!isProd) {
34-
return {};
35-
}
3636
return {
3737
headTags: [
3838
{

packages/docusaurus-plugin-google-gtag/src/index.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,10 @@ function createConfigSnippets({
3232
export default function pluginGoogleGtag(
3333
context: LoadContext,
3434
options: PluginOptions,
35-
): Plugin {
36-
const isProd = process.env.NODE_ENV === 'production';
35+
): Plugin | null {
36+
if (process.env.NODE_ENV !== 'production') {
37+
return null;
38+
}
3739

3840
const firstTrackingId = options.trackingID[0];
3941

@@ -45,13 +47,10 @@ export default function pluginGoogleGtag(
4547
},
4648

4749
getClientModules() {
48-
return isProd ? ['./gtag'] : [];
50+
return ['./gtag'];
4951
},
5052

5153
injectHtmlTags() {
52-
if (!isProd) {
53-
return {};
54-
}
5554
return {
5655
// Gtag includes GA by default, so we also preconnect to
5756
// google-analytics.

packages/docusaurus-plugin-google-tag-manager/src/index.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@ import type {PluginOptions, Options} from './options';
1616
export default function pluginGoogleAnalytics(
1717
context: LoadContext,
1818
options: PluginOptions,
19-
): Plugin {
20-
const {containerId} = options;
21-
const isProd = process.env.NODE_ENV === 'production';
19+
): Plugin | null {
20+
if (process.env.NODE_ENV !== 'production') {
21+
return null;
22+
}
2223

24+
const {containerId} = options;
2325
return {
2426
name: 'docusaurus-plugin-google-tag-manager',
2527

@@ -28,9 +30,6 @@ export default function pluginGoogleAnalytics(
2830
},
2931

3032
injectHtmlTags() {
31-
if (!isProd) {
32-
return {};
33-
}
3433
return {
3534
preBodyTags: [
3635
{

packages/docusaurus-plugin-pwa/src/index.ts

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@ import type {PluginOptions} from '@docusaurus/plugin-pwa';
1919

2020
const PluginName = 'docusaurus-plugin-pwa';
2121

22-
const isProd = process.env.NODE_ENV === 'production';
23-
2422
function getSWBabelLoader() {
2523
return {
2624
loader: 'babel-loader',
@@ -45,12 +43,21 @@ function getSWBabelLoader() {
4543
export default function pluginPWA(
4644
context: LoadContext,
4745
options: PluginOptions,
48-
): Plugin<void> {
46+
): Plugin<void> | null {
47+
if (process.env.NODE_ENV !== 'production') {
48+
return null;
49+
}
50+
if (context.siteConfig.future.experimental_router === 'hash') {
51+
logger.warn(
52+
`${PluginName} does not support the Hash Router and will be disabled.`,
53+
);
54+
return null;
55+
}
56+
4957
const {
5058
outDir,
5159
baseUrl,
5260
i18n: {currentLocale},
53-
siteConfig,
5461
} = context;
5562
const {
5663
debug,
@@ -61,13 +68,6 @@ export default function pluginPWA(
6168
swRegister,
6269
} = options;
6370

64-
if (siteConfig.future.experimental_router === 'hash') {
65-
logger.warn(
66-
`${PluginName} does not support the Hash Router and will be disabled.`,
67-
);
68-
return {name: PluginName};
69-
}
70-
7171
return {
7272
name: PluginName,
7373

@@ -79,7 +79,7 @@ export default function pluginPWA(
7979
},
8080

8181
getClientModules() {
82-
return isProd && swRegister ? [swRegister] : [];
82+
return swRegister ? [swRegister] : [];
8383
},
8484

8585
getDefaultCodeTranslationMessages() {
@@ -90,10 +90,6 @@ export default function pluginPWA(
9090
},
9191

9292
configureWebpack(config) {
93-
if (!isProd) {
94-
return {};
95-
}
96-
9793
return {
9894
plugins: [
9995
new webpack.EnvironmentPlugin({
@@ -111,37 +107,31 @@ export default function pluginPWA(
111107

112108
injectHtmlTags() {
113109
const headTags: HtmlTags = [];
114-
if (isProd) {
115-
pwaHead.forEach(({tagName, ...attributes}) => {
116-
(['href', 'content'] as const).forEach((attribute) => {
117-
const attributeValue = attributes[attribute];
118-
119-
if (!attributeValue) {
120-
return;
121-
}
122-
123-
const attributePath =
124-
!!path.extname(attributeValue) && attributeValue;
125-
126-
if (attributePath && !attributePath.startsWith(baseUrl)) {
127-
attributes[attribute] = normalizeUrl([baseUrl, attributeValue]);
128-
}
129-
});
130-
131-
return headTags.push({
132-
tagName,
133-
attributes,
134-
});
110+
pwaHead.forEach(({tagName, ...attributes}) => {
111+
(['href', 'content'] as const).forEach((attribute) => {
112+
const attributeValue = attributes[attribute];
113+
114+
if (!attributeValue) {
115+
return;
116+
}
117+
118+
const attributePath =
119+
!!path.extname(attributeValue) && attributeValue;
120+
121+
if (attributePath && !attributePath.startsWith(baseUrl)) {
122+
attributes[attribute] = normalizeUrl([baseUrl, attributeValue]);
123+
}
124+
});
125+
126+
return headTags.push({
127+
tagName,
128+
attributes,
135129
});
136-
}
130+
});
137131
return {headTags};
138132
},
139133

140134
async postBuild(props) {
141-
if (!isProd) {
142-
return;
143-
}
144-
145135
const swSourceFileTest = /\.m?js$/;
146136

147137
const swWebpackConfig: Configuration = {

packages/docusaurus-plugin-sitemap/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,12 @@ const PluginName = 'docusaurus-plugin-sitemap';
1717
export default function pluginSitemap(
1818
context: LoadContext,
1919
options: PluginOptions,
20-
): Plugin<void> {
20+
): Plugin<void> | null {
2121
if (context.siteConfig.future.experimental_router === 'hash') {
2222
logger.warn(
2323
`${PluginName} does not support the Hash Router and will be disabled.`,
2424
);
25-
return {name: PluginName};
25+
return null;
2626
}
2727

2828
return {

packages/docusaurus-plugin-vercel-analytics/src/index.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@ import type {PluginOptions, Options} from './options';
1111
export default function pluginVercelAnalytics(
1212
context: LoadContext,
1313
options: PluginOptions,
14-
): Plugin {
15-
const isProd = process.env.NODE_ENV === 'production';
16-
14+
): Plugin | null {
15+
if (process.env.NODE_ENV !== 'production') {
16+
return null;
17+
}
1718
return {
1819
name: 'docusaurus-plugin-vercel-analytics',
1920

2021
getClientModules() {
21-
return isProd ? ['./analytics'] : [];
22+
return ['./analytics'];
2223
},
2324

2425
contentLoaded({actions}) {

packages/docusaurus-types/src/plugin.d.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,10 @@ export type LoadedPlugin = InitializedPlugin & {
191191
export type PluginModule<Content = unknown> = {
192192
(context: LoadContext, options: unknown):
193193
| Plugin<Content>
194-
| Promise<Plugin<Content>>;
194+
| Promise<Plugin<Content>>
195+
| null
196+
| Promise<null>;
197+
195198
validateOptions?: <T, U>(data: OptionValidationContext<T, U>) => U;
196199
validateThemeConfig?: <T>(data: ThemeConfigValidationContext<T>) => T;
197200

packages/docusaurus/src/commands/swizzle/context.ts

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,41 @@
66
*/
77

88
import {loadContext} from '../../server/site';
9-
import {initPlugins} from '../../server/plugins/init';
9+
import {initPluginsConfigs} from '../../server/plugins/init';
1010
import {loadPluginConfigs} from '../../server/plugins/configs';
11-
import type {SwizzleCLIOptions, SwizzleContext} from './common';
11+
import type {SwizzleCLIOptions, SwizzleContext, SwizzlePlugin} from './common';
12+
import type {LoadContext} from '@docusaurus/types';
13+
14+
async function getSwizzlePlugins(
15+
context: LoadContext,
16+
): Promise<SwizzlePlugin[]> {
17+
const pluginConfigs = await loadPluginConfigs(context);
18+
const pluginConfigInitResults = await initPluginsConfigs(
19+
context,
20+
pluginConfigs,
21+
);
22+
23+
return pluginConfigInitResults.flatMap((initResult) => {
24+
// Ignore self-disabling plugins returning null
25+
if (initResult.plugin === null) {
26+
return [];
27+
}
28+
return [
29+
// TODO this is a bit confusing, need refactor
30+
{
31+
plugin: initResult.config,
32+
instance: initResult.plugin,
33+
},
34+
];
35+
});
36+
}
1237

1338
export async function initSwizzleContext(
1439
siteDir: string,
1540
options: SwizzleCLIOptions,
1641
): Promise<SwizzleContext> {
1742
const context = await loadContext({siteDir, config: options.config});
18-
const plugins = await initPlugins(context);
19-
const pluginConfigs = await loadPluginConfigs(context);
20-
2143
return {
22-
plugins: plugins.map((plugin, pluginIndex) => ({
23-
plugin: pluginConfigs[pluginIndex]!,
24-
instance: plugin,
25-
})),
44+
plugins: await getSwizzlePlugins(context),
2645
};
2746
}

packages/docusaurus/src/server/plugins/__tests__/__fixtures__/site-with-plugin/docusaurus.config.js

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)