@docusaurus/core 4.0.0-canary-6975 → 4.0.0-canary-6977

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -199,6 +199,44 @@ const VCS_CONFIG_SCHEMA = utils_validation_1.Joi.custom((input) => {
199
199
  }
200
200
  return value;
201
201
  }).default(() => exports.DEFAULT_CONFIG.vcs);
202
+ // TODO Docusaurus v5: remove this migration error for legacy template variables
203
+ const LegacySSGTemplateVariables = {
204
+ appHtml: logger_1.default.code('it.body.appHtml'),
205
+ htmlAttributes: logger_1.default.code('it.html.attributes'),
206
+ bodyAttributes: logger_1.default.code('it.body.attributes'),
207
+ metaAttributes: `${logger_1.default.code('it.head.pageTags')} (a string)`,
208
+ headTags: logger_1.default.code('it.head.pluginTags'),
209
+ preBodyTags: logger_1.default.code('it.body.preTags'),
210
+ postBodyTags: logger_1.default.code('it.body.postTags'),
211
+ stylesheets: `${logger_1.default.code('it.assets.stylesheets')} (URLs including the baseUrl)`,
212
+ scripts: `${logger_1.default.code('it.assets.scripts')} (URLs including the baseUrl)`,
213
+ noIndex: `removed: the ${logger_1.default.code('<meta name="robots">')} tag is part of ${logger_1.default.code('it.head.pageTags')}`,
214
+ };
215
+ function getLegacySSGTemplateVariablesMessage(template) {
216
+ const usedLegacyVariables = Object.keys(LegacySSGTemplateVariables).filter((name) => new RegExp(String.raw `\bit\.${name}\b`).test(template));
217
+ if (usedLegacyVariables.length === 0) {
218
+ return undefined;
219
+ }
220
+ return usedLegacyVariables
221
+ .map((name) => `- ${logger_1.default.code(`it.${name}`)} => ${LegacySSGTemplateVariables[name]}`)
222
+ .join('\n');
223
+ }
224
+ const SSG_TEMPLATE_SCHEMA = utils_validation_1.Joi.string()
225
+ // TODO Docusaurus v5: remove this migration error
226
+ .custom((template, helpers) => {
227
+ const legacyVariablesMessage = getLegacySSGTemplateVariablesMessage(template);
228
+ if (legacyVariablesMessage) {
229
+ return helpers.error('docusaurus.legacyVariables', {
230
+ legacyVariablesMessage,
231
+ });
232
+ }
233
+ return template;
234
+ })
235
+ .messages({
236
+ 'docusaurus.legacyVariables': `The Docusaurus config ${logger_1.default.code('siteConfig.ssgTemplate')} uses template variables that have been renamed or removed:
237
+ {#legacyVariablesMessage}
238
+ Please update your template.`,
239
+ });
202
240
  // TODO Docusaurus v5: remove these never types for removed/renamed options
203
241
  const FUTURE_CONFIG_SCHEMA = utils_validation_1.Joi.object({
204
242
  // TODO Docusaurus v5: remove this migration error
@@ -278,7 +316,7 @@ exports.ConfigSchema = utils_validation_1.Joi.object({
278
316
  'array.includes': '{#label} is invalid. A script must be a plain string (the src), or an object with at least a "src" property.',
279
317
  })
280
318
  .default(exports.DEFAULT_CONFIG.scripts),
281
- ssgTemplate: utils_validation_1.Joi.string(),
319
+ ssgTemplate: SSG_TEMPLATE_SCHEMA,
282
320
  // TODO Docusaurus v5: remove this migration error
283
321
  ssrTemplate: utils_validation_1.Joi.any()
284
322
  .forbidden()
@@ -14,7 +14,6 @@ export type SSGParams = {
14
14
  postBodyTags: string;
15
15
  outDir: string;
16
16
  baseUrl: string;
17
- noIndex: boolean;
18
17
  DOCUSAURUS_VERSION: string;
19
18
  serverBundlePath: string;
20
19
  ssgTemplateContent: string;
@@ -23,7 +23,6 @@ async function createSSGParams({ props, serverBundlePath, clientManifestPath, })
23
23
  preBodyTags: props.preBodyTags,
24
24
  postBodyTags: props.postBodyTags,
25
25
  ssgTemplateContent: props.siteConfig.ssgTemplate ?? ssgTemplate_html_1.default,
26
- noIndex: props.siteConfig.noIndex,
27
26
  DOCUSAURUS_VERSION: utils_1.DOCUSAURUS_VERSION,
28
27
  serverBundlePath,
29
28
  };
@@ -6,19 +6,42 @@
6
6
  */
7
7
  import type { SSGParams } from './ssgParams';
8
8
  import type { AppRenderResult } from '../common';
9
+ /**
10
+ * The data that the `siteConfig.ssgTemplate` receives as the `it` variable.
11
+ * Changing it is a breaking change because the template is configurable.
12
+ * Attributes and tags are pre-rendered HTML strings.
13
+ */
9
14
  type SSGTemplateData = {
10
- appHtml: string;
11
- baseUrl: string;
12
- htmlAttributes: string;
13
- bodyAttributes: string;
14
- headTags: string;
15
- preBodyTags: string;
16
- postBodyTags: string;
17
- metaAttributes: string[];
18
- scripts: string[];
19
- stylesheets: string[];
20
- noIndex: boolean;
15
+ /** The Docusaurus version */
21
16
  version: string;
17
+ /** The site base URL, or `./` with the hash router */
18
+ baseUrl: string;
19
+ html: {
20
+ /** The `<html>` attributes, set by the page with `<Head>` */
21
+ attributes: string;
22
+ };
23
+ head: {
24
+ /** The `<head>` tags set by the page with `<Head>` */
25
+ pageTags: string;
26
+ /** The `headTags` of the plugins `injectHtmlTags()` lifecycle */
27
+ pluginTags: string;
28
+ };
29
+ body: {
30
+ /** The `<body>` attributes, set by the page with `<Head>` */
31
+ attributes: string;
32
+ /** The `preBodyTags` of the plugins `injectHtmlTags()` lifecycle */
33
+ preTags: string;
34
+ /** The server-side rendered React app */
35
+ appHtml: string;
36
+ /** The `postBodyTags` of the plugins `injectHtmlTags()` lifecycle */
37
+ postTags: string;
38
+ };
39
+ assets: {
40
+ /** The URLs of the CSS files the page needs */
41
+ stylesheets: string[];
42
+ /** The URLs of the JS files the page needs */
43
+ scripts: string[];
44
+ };
22
45
  };
23
46
  export type SSGTemplateCompiled = (data: SSGTemplateData) => string;
24
47
  export declare function compileSSGTemplate(template: string): Promise<SSGTemplateCompiled>;
@@ -4,5 +4,5 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- declare const _default = "\n<!DOCTYPE html>\n<html <%~ it.htmlAttributes %>>\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"generator\" content=\"Docusaurus v<%= it.version %>\">\n <% it.metaAttributes.forEach((metaAttribute) => { %>\n <%~ metaAttribute %>\n <% }); %>\n <%~ it.headTags %>\n <% it.stylesheets.forEach((stylesheet) => { %>\n <link rel=\"stylesheet\" href=\"<%= it.baseUrl %><%= stylesheet %>\" />\n <% }); %>\n <% it.scripts.forEach((script) => { %>\n <script src=\"<%= it.baseUrl %><%= script %>\" defer></script>\n <% }); %>\n </head>\n <body <%~ it.bodyAttributes %>>\n <%~ it.preBodyTags %>\n <div id=\"__docusaurus\"><%~ it.appHtml %></div>\n <%~ it.postBodyTags %>\n </body>\n</html>\n";
7
+ declare const _default = "\n<!DOCTYPE html>\n<html <%~ it.html.attributes %>>\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"generator\" content=\"Docusaurus v<%= it.version %>\">\n <%~ it.head.pageTags %>\n <%~ it.head.pluginTags %>\n <% it.assets.stylesheets.forEach((stylesheet) => { %>\n <link rel=\"stylesheet\" href=\"<%= stylesheet %>\" />\n <% }); %>\n <% it.assets.scripts.forEach((script) => { %>\n <script src=\"<%= script %>\" defer></script>\n <% }); %>\n </head>\n <body <%~ it.body.attributes %>>\n <%~ it.body.preTags %>\n <div id=\"__docusaurus\"><%~ it.body.appHtml %></div>\n <%~ it.body.postTags %>\n </body>\n</html>\n";
8
8
  export default _default;
@@ -8,25 +8,23 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.default = `
10
10
  <!DOCTYPE html>
11
- <html <%~ it.htmlAttributes %>>
11
+ <html <%~ it.html.attributes %>>
12
12
  <head>
13
13
  <meta charset="UTF-8">
14
14
  <meta name="generator" content="Docusaurus v<%= it.version %>">
15
- <% it.metaAttributes.forEach((metaAttribute) => { %>
16
- <%~ metaAttribute %>
15
+ <%~ it.head.pageTags %>
16
+ <%~ it.head.pluginTags %>
17
+ <% it.assets.stylesheets.forEach((stylesheet) => { %>
18
+ <link rel="stylesheet" href="<%= stylesheet %>" />
17
19
  <% }); %>
18
- <%~ it.headTags %>
19
- <% it.stylesheets.forEach((stylesheet) => { %>
20
- <link rel="stylesheet" href="<%= it.baseUrl %><%= stylesheet %>" />
21
- <% }); %>
22
- <% it.scripts.forEach((script) => { %>
23
- <script src="<%= it.baseUrl %><%= script %>" defer></script>
20
+ <% it.assets.scripts.forEach((script) => { %>
21
+ <script src="<%= script %>" defer></script>
24
22
  <% }); %>
25
23
  </head>
26
- <body <%~ it.bodyAttributes %>>
27
- <%~ it.preBodyTags %>
28
- <div id="__docusaurus"><%~ it.appHtml %></div>
29
- <%~ it.postBodyTags %>
24
+ <body <%~ it.body.attributes %>>
25
+ <%~ it.body.preTags %>
26
+ <div id="__docusaurus"><%~ it.body.appHtml %></div>
27
+ <%~ it.body.postTags %>
30
28
  </body>
31
29
  </html>
32
30
  `;
@@ -18,69 +18,57 @@ async function compileSSGTemplate(template) {
18
18
  return (data) => eta.render(compiledTemplate, data);
19
19
  }
20
20
  /**
21
- * Given a list of modules that were SSR an d
22
- * @param modules
23
- * @param manifest
21
+ * Returns the URLs of the JS/CSS assets required to render a page, based on
22
+ * the modules that were server-side rendered and the client manifest.
24
23
  */
25
- function getScriptsAndStylesheets({ modules, manifest, }) {
26
- // Get all required assets for this particular page
27
- // based on client manifest information.
28
- const modulesToBeLoaded = [...manifest.entrypoints, ...Array.from(modules)];
24
+ function getAssets({ baseUrl, modules, manifest, }) {
25
+ const modulesToBeLoaded = [...manifest.entrypoints, ...modules];
29
26
  const bundles = (0, react_loadable_ssr_addon_v5_slorber_1.getBundles)(manifest, modulesToBeLoaded);
30
- const stylesheets = (bundles.css ?? []).map((b) => b.file);
31
- const scripts = (bundles.js ?? []).map((b) => b.file);
32
- return { scripts, stylesheets };
27
+ const toUrl = (bundle) => `${baseUrl}${bundle.file}`;
28
+ return {
29
+ stylesheets: (bundles.css ?? []).map(toUrl),
30
+ scripts: (bundles.js ?? []).map(toUrl),
31
+ };
33
32
  }
34
33
  function renderSSGTemplate({ params, result, ssgTemplate, }) {
35
- const { baseUrl, headTags, preBodyTags, postBodyTags, manifest, noIndex, DOCUSAURUS_VERSION, } = params;
34
+ const { baseUrl, headTags, preBodyTags, postBodyTags, manifest, DOCUSAURUS_VERSION, } = params;
36
35
  const { html: appHtml, collectedData: { modules, metadata }, } = result;
37
- const { scripts, stylesheets } = getScriptsAndStylesheets({ manifest, modules });
38
- const { htmlAttributes, bodyAttributes } = metadata.internal;
39
- const metaStrings = [
40
- metadata.internal.title,
41
- metadata.internal.meta,
42
- metadata.internal.link,
43
- metadata.internal.script,
44
- ];
45
- const metaAttributes = metaStrings.filter(Boolean);
36
+ const { htmlAttributes, bodyAttributes, title, meta, link, script } = metadata.internal;
46
37
  const data = {
47
- appHtml,
48
- baseUrl,
49
- htmlAttributes,
50
- bodyAttributes,
51
- headTags,
52
- preBodyTags,
53
- postBodyTags,
54
- metaAttributes,
55
- scripts,
56
- stylesheets,
57
- noIndex,
58
38
  version: DOCUSAURUS_VERSION,
39
+ baseUrl,
40
+ html: { attributes: htmlAttributes },
41
+ head: {
42
+ pageTags: [title, meta, link, script].join(''),
43
+ pluginTags: headTags,
44
+ },
45
+ body: {
46
+ attributes: bodyAttributes,
47
+ preTags: preBodyTags,
48
+ appHtml,
49
+ postTags: postBodyTags,
50
+ },
51
+ assets: getAssets({ baseUrl, manifest, modules }),
59
52
  };
60
53
  return ssgTemplate(data);
61
54
  }
62
55
  async function renderHashRouterTemplate({ params, }) {
63
- const {
64
- // baseUrl,
65
- headTags, preBodyTags, postBodyTags, manifest, DOCUSAURUS_VERSION, ssgTemplateContent, } = params;
56
+ const { headTags, preBodyTags, postBodyTags, manifest, DOCUSAURUS_VERSION, ssgTemplateContent, } = params;
66
57
  const ssgTemplate = await logger_1.PerfLogger.async('Compile SSG template', () => compileSSGTemplate(ssgTemplateContent));
67
- const { scripts, stylesheets } = getScriptsAndStylesheets({
68
- manifest,
69
- modules: [],
70
- });
58
+ // The hash router site can be opened from the file system: use relative URLs
59
+ const baseUrl = './';
71
60
  const data = {
72
- appHtml: '',
73
- baseUrl: './',
74
- htmlAttributes: '',
75
- bodyAttributes: '',
76
- headTags,
77
- preBodyTags,
78
- postBodyTags,
79
- metaAttributes: [],
80
- scripts,
81
- stylesheets,
82
- noIndex: false,
83
61
  version: DOCUSAURUS_VERSION,
62
+ baseUrl,
63
+ html: { attributes: '' },
64
+ head: { pageTags: '', pluginTags: headTags },
65
+ body: {
66
+ attributes: '',
67
+ preTags: preBodyTags,
68
+ appHtml: '',
69
+ postTags: postBodyTags,
70
+ },
71
+ assets: getAssets({ baseUrl, manifest, modules: [] }),
84
72
  };
85
73
  return ssgTemplate(data);
86
74
  }
@@ -70,9 +70,12 @@ async function createBaseConfig({ props, isServer, minify, configureWebpackUtils
70
70
  // Because Webpack does not evict the cache on alias/swizzle changes,
71
71
  // See https://github.com/webpack/webpack/issues/13627
72
72
  const themeAliasesHash = (0, utils_1.md5Hash)(JSON.stringify(themeAliases));
73
+ // Loader and minimizer options are not part of the cache key
74
+ // Changing the Browserslist config must evict the cache
75
+ const browserslistHash = (0, utils_1.md5Hash)(JSON.stringify((0, bundler_1.getBrowserslistQueries)()));
73
76
  // Asset module parser options are not part of the cache key
74
77
  // Changing the asset inline max size must evict the cache
75
- return `${siteMetadata.docusaurusVersion}-${themeAliasesHash}-${utils_1.ASSET_INLINE_MAX_SIZE}`;
78
+ return `${siteMetadata.docusaurusVersion}-${themeAliasesHash}-${browserslistHash}-${utils_1.ASSET_INLINE_MAX_SIZE}`;
76
79
  }
77
80
  // When one of those modules/dependencies change (including transitive
78
81
  // deps), cache is invalidated
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@docusaurus/core",
3
3
  "description": "Easy to Maintain Open Source Documentation Websites",
4
- "version": "4.0.0-canary-6975",
4
+ "version": "4.0.0-canary-6977",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
7
7
  "access": "public"
@@ -27,15 +27,15 @@
27
27
  "url": "https://github.com/facebook/docusaurus/issues"
28
28
  },
29
29
  "dependencies": {
30
- "@docusaurus/babel": "4.0.0-canary-6975",
31
- "@docusaurus/bundler": "4.0.0-canary-6975",
32
- "@docusaurus/fs": "4.0.0-canary-6975",
33
- "@docusaurus/glob": "4.0.0-canary-6975",
34
- "@docusaurus/logger": "4.0.0-canary-6975",
35
- "@docusaurus/mdx-loader": "4.0.0-canary-6975",
36
- "@docusaurus/utils": "4.0.0-canary-6975",
37
- "@docusaurus/utils-common": "4.0.0-canary-6975",
38
- "@docusaurus/utils-validation": "4.0.0-canary-6975",
30
+ "@docusaurus/babel": "4.0.0-canary-6977",
31
+ "@docusaurus/bundler": "4.0.0-canary-6977",
32
+ "@docusaurus/fs": "4.0.0-canary-6977",
33
+ "@docusaurus/glob": "4.0.0-canary-6977",
34
+ "@docusaurus/logger": "4.0.0-canary-6977",
35
+ "@docusaurus/mdx-loader": "4.0.0-canary-6977",
36
+ "@docusaurus/utils": "4.0.0-canary-6977",
37
+ "@docusaurus/utils-common": "4.0.0-canary-6977",
38
+ "@docusaurus/utils-validation": "4.0.0-canary-6977",
39
39
  "@rspack/core": "^2.2.3",
40
40
  "@rspack/dev-server": "^2.2.1",
41
41
  "boxen": "^9.0.0",
@@ -68,8 +68,8 @@
68
68
  "webpack-merge": "^6.0.1"
69
69
  },
70
70
  "devDependencies": {
71
- "@docusaurus/module-type-aliases": "4.0.0-canary-6975",
72
- "@docusaurus/types": "4.0.0-canary-6975",
71
+ "@docusaurus/module-type-aliases": "4.0.0-canary-6977",
72
+ "@docusaurus/types": "4.0.0-canary-6977",
73
73
  "@total-typescript/shoehorn": "^0.1.2",
74
74
  "@types/escape-html": "^1.0.4",
75
75
  "@types/history": "^4.7.11",