Skip to content

Commit 98aab81

Browse files
slorbermariuszkrzaczkowskiDevJoaoLopes
authored
feat(core): Docusaurus Faster - SSG worker threads (#10826)
Co-authored-by: Sébastien Lorber <[email protected]> Co-authored-by: Mariusz Krzaczkowski <[email protected]> Co-authored-by: João Victor Lopes <[email protected]> Co-authored-by: slorber <[email protected]>
1 parent 042070c commit 98aab81

18 files changed

+767
-204
lines changed

.cspell.json

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
],
2222
"ignorePaths": [
2323
"CHANGELOG.md",
24+
"patches",
2425
"packages/docusaurus-theme-translations/locales",
2526
"package.json",
2627
"yarn.lock",

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
"canary:bumpVersion": "yarn lerna version `yarn --silent canary:version` --exact --no-push --yes",
5151
"canary:publish": "yarn lerna publish from-package --dist-tag canary --yes --no-verify-access",
5252
"changelog": "lerna-changelog",
53-
"postinstall": "yarn lock:update && yarn build:packages",
53+
"postinstall": "patch-package && yarn lock:update && yarn build:packages",
5454
"prepare": "husky install",
5555
"format": "prettier --write .",
5656
"format:diff": "prettier --list-different .",
@@ -112,6 +112,8 @@
112112
"lint-staged": "~13.2.3",
113113
"lockfile-lint": "^4.14.0",
114114
"npm-run-all": "^4.1.5",
115+
"patch-package": "^8.0.0",
116+
"postinstall-postinstall": "^2.1.0",
115117
"prettier": "^2.8.8",
116118
"react": "^18.0.0",
117119
"react-dom": "^18.0.0",

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

+1
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ export type FasterConfig = {
130130
lightningCssMinimizer: boolean;
131131
mdxCrossCompilerCache: boolean;
132132
rspackBundler: boolean;
133+
ssgWorkerThreads: boolean;
133134
};
134135

135136
export type FutureV4Config = {

packages/docusaurus/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"semver": "^7.5.4",
7070
"serve-handler": "^6.1.6",
7171
"shelljs": "^0.8.5",
72+
"tinypool": "^1.0.2",
7273
"tslib": "^2.6.0",
7374
"update-notifier": "^6.0.2",
7475
"webpack": "^5.95.0",

packages/docusaurus/src/server/__tests__/__snapshots__/config.test.ts.snap

+10
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ exports[`loadSiteConfig website with .cjs siteConfig 1`] = `
1212
"lightningCssMinimizer": false,
1313
"mdxCrossCompilerCache": false,
1414
"rspackBundler": false,
15+
"ssgWorkerThreads": false,
1516
"swcHtmlMinimizer": false,
1617
"swcJsLoader": false,
1718
"swcJsMinimizer": false,
@@ -84,6 +85,7 @@ exports[`loadSiteConfig website with ts + js config 1`] = `
8485
"lightningCssMinimizer": false,
8586
"mdxCrossCompilerCache": false,
8687
"rspackBundler": false,
88+
"ssgWorkerThreads": false,
8789
"swcHtmlMinimizer": false,
8890
"swcJsLoader": false,
8991
"swcJsMinimizer": false,
@@ -156,6 +158,7 @@ exports[`loadSiteConfig website with valid JS CJS config 1`] = `
156158
"lightningCssMinimizer": false,
157159
"mdxCrossCompilerCache": false,
158160
"rspackBundler": false,
161+
"ssgWorkerThreads": false,
159162
"swcHtmlMinimizer": false,
160163
"swcJsLoader": false,
161164
"swcJsMinimizer": false,
@@ -228,6 +231,7 @@ exports[`loadSiteConfig website with valid JS ESM config 1`] = `
228231
"lightningCssMinimizer": false,
229232
"mdxCrossCompilerCache": false,
230233
"rspackBundler": false,
234+
"ssgWorkerThreads": false,
231235
"swcHtmlMinimizer": false,
232236
"swcJsLoader": false,
233237
"swcJsMinimizer": false,
@@ -300,6 +304,7 @@ exports[`loadSiteConfig website with valid TypeScript CJS config 1`] = `
300304
"lightningCssMinimizer": false,
301305
"mdxCrossCompilerCache": false,
302306
"rspackBundler": false,
307+
"ssgWorkerThreads": false,
303308
"swcHtmlMinimizer": false,
304309
"swcJsLoader": false,
305310
"swcJsMinimizer": false,
@@ -372,6 +377,7 @@ exports[`loadSiteConfig website with valid TypeScript ESM config 1`] = `
372377
"lightningCssMinimizer": false,
373378
"mdxCrossCompilerCache": false,
374379
"rspackBundler": false,
380+
"ssgWorkerThreads": false,
375381
"swcHtmlMinimizer": false,
376382
"swcJsLoader": false,
377383
"swcJsMinimizer": false,
@@ -444,6 +450,7 @@ exports[`loadSiteConfig website with valid async config 1`] = `
444450
"lightningCssMinimizer": false,
445451
"mdxCrossCompilerCache": false,
446452
"rspackBundler": false,
453+
"ssgWorkerThreads": false,
447454
"swcHtmlMinimizer": false,
448455
"swcJsLoader": false,
449456
"swcJsMinimizer": false,
@@ -518,6 +525,7 @@ exports[`loadSiteConfig website with valid async config creator function 1`] = `
518525
"lightningCssMinimizer": false,
519526
"mdxCrossCompilerCache": false,
520527
"rspackBundler": false,
528+
"ssgWorkerThreads": false,
521529
"swcHtmlMinimizer": false,
522530
"swcJsLoader": false,
523531
"swcJsMinimizer": false,
@@ -592,6 +600,7 @@ exports[`loadSiteConfig website with valid config creator function 1`] = `
592600
"lightningCssMinimizer": false,
593601
"mdxCrossCompilerCache": false,
594602
"rspackBundler": false,
603+
"ssgWorkerThreads": false,
595604
"swcHtmlMinimizer": false,
596605
"swcJsLoader": false,
597606
"swcJsMinimizer": false,
@@ -669,6 +678,7 @@ exports[`loadSiteConfig website with valid siteConfig 1`] = `
669678
"lightningCssMinimizer": false,
670679
"mdxCrossCompilerCache": false,
671680
"rspackBundler": false,
681+
"ssgWorkerThreads": false,
672682
"swcHtmlMinimizer": false,
673683
"swcJsLoader": false,
674684
"swcJsMinimizer": false,

packages/docusaurus/src/server/__tests__/__snapshots__/site.test.ts.snap

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ exports[`load loads props for site with custom i18n path 1`] = `
8686
"lightningCssMinimizer": false,
8787
"mdxCrossCompilerCache": false,
8888
"rspackBundler": false,
89+
"ssgWorkerThreads": false,
8990
"swcHtmlMinimizer": false,
9091
"swcJsLoader": false,
9192
"swcJsMinimizer": false,

packages/docusaurus/src/server/__tests__/configValidation.test.ts

+143-2
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ describe('normalizeConfig', () => {
5858
lightningCssMinimizer: true,
5959
mdxCrossCompilerCache: true,
6060
rspackBundler: true,
61+
ssgWorkerThreads: true,
6162
},
6263
experimental_storage: {
6364
type: 'sessionStorage',
@@ -760,6 +761,7 @@ describe('future', () => {
760761
lightningCssMinimizer: true,
761762
mdxCrossCompilerCache: true,
762763
rspackBundler: true,
764+
ssgWorkerThreads: true,
763765
},
764766
experimental_storage: {
765767
type: 'sessionStorage',
@@ -1113,10 +1115,12 @@ describe('future', () => {
11131115
lightningCssMinimizer: true,
11141116
mdxCrossCompilerCache: true,
11151117
rspackBundler: true,
1118+
ssgWorkerThreads: true,
11161119
};
11171120
expect(
11181121
normalizeConfig({
11191122
future: {
1123+
v4: true,
11201124
experimental_faster: faster,
11211125
},
11221126
}),
@@ -1131,14 +1135,45 @@ describe('future', () => {
11311135
).toEqual(fasterContaining(DEFAULT_FASTER_CONFIG));
11321136
});
11331137

1134-
it('accepts faster - true', () => {
1138+
it('accepts faster - true (v4: true)', () => {
11351139
expect(
11361140
normalizeConfig({
1137-
future: {experimental_faster: true},
1141+
future: {
1142+
v4: true,
1143+
experimental_faster: true,
1144+
},
11381145
}),
11391146
).toEqual(fasterContaining(DEFAULT_FASTER_CONFIG_TRUE));
11401147
});
11411148

1149+
it('rejects faster - true (v4: false)', () => {
1150+
expect(() =>
1151+
normalizeConfig({
1152+
future: {
1153+
v4: false,
1154+
experimental_faster: true,
1155+
},
1156+
}),
1157+
).toThrowErrorMatchingInlineSnapshot(`
1158+
"Docusaurus config \`future.experimental_faster.ssgWorkerThreads\` requires the future flag \`future.v4.removeLegacyPostBuildHeadAttribute\` to be turned on.
1159+
If you use Docusaurus Faster, we recommend that you also activate Docusaurus v4 future flags: \`{future: {v4: true}}\`"
1160+
`);
1161+
});
1162+
1163+
it('rejects faster - true (v4: undefined)', () => {
1164+
expect(() =>
1165+
normalizeConfig({
1166+
future: {
1167+
v4: false,
1168+
experimental_faster: true,
1169+
},
1170+
}),
1171+
).toThrowErrorMatchingInlineSnapshot(`
1172+
"Docusaurus config \`future.experimental_faster.ssgWorkerThreads\` requires the future flag \`future.v4.removeLegacyPostBuildHeadAttribute\` to be turned on.
1173+
If you use Docusaurus Faster, we recommend that you also activate Docusaurus v4 future flags: \`{future: {v4: true}}\`"
1174+
`);
1175+
});
1176+
11421177
it('rejects faster - number', () => {
11431178
// @ts-expect-error: invalid
11441179
const faster: Partial<FasterConfig> = 42;
@@ -1579,6 +1614,112 @@ describe('future', () => {
15791614
`);
15801615
});
15811616
});
1617+
1618+
describe('ssgWorkerThreads', () => {
1619+
it('accepts - undefined', () => {
1620+
const faster: Partial<FasterConfig> = {
1621+
ssgWorkerThreads: undefined,
1622+
};
1623+
expect(
1624+
normalizeConfig({
1625+
future: {
1626+
experimental_faster: faster,
1627+
},
1628+
}),
1629+
).toEqual(fasterContaining({ssgWorkerThreads: false}));
1630+
});
1631+
1632+
it('accepts - true (v4: true)', () => {
1633+
const faster: Partial<FasterConfig> = {
1634+
ssgWorkerThreads: true,
1635+
};
1636+
expect(
1637+
normalizeConfig({
1638+
future: {
1639+
v4: true,
1640+
experimental_faster: faster,
1641+
},
1642+
}),
1643+
).toEqual(fasterContaining({ssgWorkerThreads: true}));
1644+
});
1645+
1646+
it('rejects - true (v4: false)', () => {
1647+
const faster: Partial<FasterConfig> = {
1648+
ssgWorkerThreads: true,
1649+
};
1650+
expect(() =>
1651+
normalizeConfig({
1652+
future: {
1653+
v4: false,
1654+
experimental_faster: faster,
1655+
},
1656+
}),
1657+
).toThrowErrorMatchingInlineSnapshot(`
1658+
"Docusaurus config \`future.experimental_faster.ssgWorkerThreads\` requires the future flag \`future.v4.removeLegacyPostBuildHeadAttribute\` to be turned on.
1659+
If you use Docusaurus Faster, we recommend that you also activate Docusaurus v4 future flags: \`{future: {v4: true}}\`"
1660+
`);
1661+
});
1662+
1663+
it('rejects - true (v4: undefined)', () => {
1664+
const faster: Partial<FasterConfig> = {
1665+
ssgWorkerThreads: true,
1666+
};
1667+
expect(() =>
1668+
normalizeConfig({
1669+
future: {
1670+
v4: undefined,
1671+
experimental_faster: faster,
1672+
},
1673+
}),
1674+
).toThrowErrorMatchingInlineSnapshot(`
1675+
"Docusaurus config \`future.experimental_faster.ssgWorkerThreads\` requires the future flag \`future.v4.removeLegacyPostBuildHeadAttribute\` to be turned on.
1676+
If you use Docusaurus Faster, we recommend that you also activate Docusaurus v4 future flags: \`{future: {v4: true}}\`"
1677+
`);
1678+
});
1679+
1680+
it('accepts - false', () => {
1681+
const faster: Partial<FasterConfig> = {
1682+
ssgWorkerThreads: false,
1683+
};
1684+
expect(
1685+
normalizeConfig({
1686+
future: {
1687+
experimental_faster: faster,
1688+
},
1689+
}),
1690+
).toEqual(fasterContaining({ssgWorkerThreads: false}));
1691+
});
1692+
1693+
it('rejects - null', () => {
1694+
// @ts-expect-error: invalid
1695+
const faster: Partial<FasterConfig> = {ssgWorkerThreads: 42};
1696+
expect(() =>
1697+
normalizeConfig({
1698+
future: {
1699+
experimental_faster: faster,
1700+
},
1701+
}),
1702+
).toThrowErrorMatchingInlineSnapshot(`
1703+
""future.experimental_faster.ssgWorkerThreads" must be a boolean
1704+
"
1705+
`);
1706+
});
1707+
1708+
it('rejects - number', () => {
1709+
// @ts-expect-error: invalid
1710+
const faster: Partial<FasterConfig> = {ssgWorkerThreads: 42};
1711+
expect(() =>
1712+
normalizeConfig({
1713+
future: {
1714+
experimental_faster: faster,
1715+
},
1716+
}),
1717+
).toThrowErrorMatchingInlineSnapshot(`
1718+
""future.experimental_faster.ssgWorkerThreads" must be a boolean
1719+
"
1720+
`);
1721+
});
1722+
});
15821723
});
15831724

15841725
describe('v4', () => {

packages/docusaurus/src/server/configValidation.ts

+30-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
addLeadingSlash,
1717
removeTrailingSlash,
1818
} from '@docusaurus/utils-common';
19+
import logger from '@docusaurus/logger';
1920
import type {
2021
FasterConfig,
2122
FutureConfig,
@@ -49,6 +50,7 @@ export const DEFAULT_FASTER_CONFIG: FasterConfig = {
4950
lightningCssMinimizer: false,
5051
mdxCrossCompilerCache: false,
5152
rspackBundler: false,
53+
ssgWorkerThreads: false,
5254
};
5355

5456
// When using the "faster: true" shortcut
@@ -59,6 +61,7 @@ export const DEFAULT_FASTER_CONFIG_TRUE: FasterConfig = {
5961
lightningCssMinimizer: true,
6062
mdxCrossCompilerCache: true,
6163
rspackBundler: true,
64+
ssgWorkerThreads: true,
6265
};
6366

6467
export const DEFAULT_FUTURE_V4_CONFIG: FutureV4Config = {
@@ -243,6 +246,9 @@ const FASTER_CONFIG_SCHEMA = Joi.alternatives()
243246
DEFAULT_FASTER_CONFIG.mdxCrossCompilerCache,
244247
),
245248
rspackBundler: Joi.boolean().default(DEFAULT_FASTER_CONFIG.rspackBundler),
249+
ssgWorkerThreads: Joi.boolean().default(
250+
DEFAULT_FASTER_CONFIG.ssgWorkerThreads,
251+
),
246252
}),
247253
Joi.boolean()
248254
.required()
@@ -445,6 +451,26 @@ export const ConfigSchema = Joi.object<DocusaurusConfig>({
445451
'Docusaurus config validation warning. Field {#label}: {#warningMessage}',
446452
});
447453

454+
// Expressing this kind of logic in Joi is a pain
455+
// We also want to decouple logic from Joi: easier to remove it later!
456+
function ensureDocusaurusConfigConsistency(config: DocusaurusConfig) {
457+
if (
458+
config.future.experimental_faster.ssgWorkerThreads &&
459+
!config.future.v4.removeLegacyPostBuildHeadAttribute
460+
) {
461+
throw new Error(
462+
`Docusaurus config ${logger.code(
463+
'future.experimental_faster.ssgWorkerThreads',
464+
)} requires the future flag ${logger.code(
465+
'future.v4.removeLegacyPostBuildHeadAttribute',
466+
)} to be turned on.
467+
If you use Docusaurus Faster, we recommend that you also activate Docusaurus v4 future flags: ${logger.code(
468+
'{future: {v4: true}}',
469+
)}`,
470+
);
471+
}
472+
}
473+
448474
// TODO move to @docusaurus/utils-validation
449475
export function validateConfig(
450476
config: unknown,
@@ -476,7 +502,9 @@ export function validateConfig(
476502
? `${formattedError}These field(s) (${unknownFields}) are not recognized in ${siteConfigPath}.\nIf you still want these fields to be in your configuration, put them in the "customFields" field.\nSee https://docusaurus.io/docs/api/docusaurus-config/#customfields`
477503
: formattedError;
478504
throw new Error(formattedError);
479-
} else {
480-
return value;
481505
}
506+
507+
ensureDocusaurusConfigConsistency(value);
508+
509+
return value;
482510
}

0 commit comments

Comments
 (0)