From 1c2b05baba17cd9ff61abc257029575a53f4df63 Mon Sep 17 00:00:00 2001 From: ozakione <29860391+OzakIOne@users.noreply.github.com> Date: Wed, 11 Oct 2023 16:50:45 +0200 Subject: [PATCH 01/24] wip: unused directives plugin --- .../docusaurus-mdx-loader/src/processor.ts | 2 + .../__tests__/__fixtures__/directives.md | 20 +++++ .../__snapshots__/index.test.ts.snap | 13 ++++ .../unusedDirectives/__tests__/index.test.ts | 49 ++++++++++++ .../src/remark/unusedDirectives/index.ts | 74 +++++++++++++++++++ 5 files changed, 158 insertions(+) create mode 100644 packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/directives.md create mode 100644 packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap create mode 100644 packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts create mode 100644 packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts diff --git a/packages/docusaurus-mdx-loader/src/processor.ts b/packages/docusaurus-mdx-loader/src/processor.ts index 5cc5699d6804..1b6a73754a7a 100644 --- a/packages/docusaurus-mdx-loader/src/processor.ts +++ b/packages/docusaurus-mdx-loader/src/processor.ts @@ -14,6 +14,7 @@ import details from './remark/details'; import head from './remark/head'; import mermaid from './remark/mermaid'; import transformAdmonitions from './remark/admonitions'; +import unusedDirectivesWarning from './remark/unusedDirectives'; import codeCompatPlugin from './remark/mdx1Compat/codeCompatPlugin'; import {getFormat} from './format'; import type {MDXFrontMatter} from './frontMatter'; @@ -114,6 +115,7 @@ async function createProcessorFactory() { gfm, options.markdownConfig.mdx1Compat.comments ? comment : null, ...(options.remarkPlugins ?? []), + unusedDirectivesWarning, ].filter((plugin): plugin is MDXPlugin => Boolean(plugin)); // codeCompatPlugin needs to be applied last after user-provided plugins diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/directives.md b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/directives.md new file mode 100644 index 000000000000..2ca41c7e9e9e --- /dev/null +++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/directives.md @@ -0,0 +1,20 @@ +Test directives + +:base + +Text:base + +Text: base + +::base + +:::base + +::::info **Weather** +On nice days, you can enjoy skiing in the mountains. + +:::danger *Storms* +Take care of snowstorms... +::: + +:::: diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap new file mode 100644 index 000000000000..0c4fd3d8244a --- /dev/null +++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap @@ -0,0 +1,13 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`directives remark plugin default behavior for custom keyword 1`] = ` +"
Test directives
+ +Text
+Text: base
+ +::::info Weather +On nice days, you can enjoy skiing in the mountains.
:::danger Storms +Take care of snowstorms...
::::
" +`; diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts new file mode 100644 index 000000000000..205ecf6aa058 --- /dev/null +++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts @@ -0,0 +1,49 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import path from 'path'; +import remark2rehype from 'remark-rehype'; +import stringify from 'rehype-stringify'; +import vfile from 'to-vfile'; +import preprocessor from '../../../preprocessor'; +import plugin from '../index'; + +const processFixture = async (name: string) => { + const {remark} = await import('remark'); + const {default: directives} = await import('remark-directive'); + + const filePath = path.join(__dirname, '__fixtures__', `${name}.md`); + const file = await vfile.read(filePath); + const fileContentPreprocessed = preprocessor({ + fileContent: file.toString(), + filePath, + markdownConfig: { + mermaid: false, + mdx1Compat: { + admonitions: false, + comments: false, + headingIds: false, + }, + }, + }); + + const result = await remark() + .use(directives) + .use(plugin) + .use(remark2rehype) + .use(stringify) + .process(fileContentPreprocessed); + + return result.value; +}; + +describe('directives remark plugin', () => { + it('default behavior for custom keyword', async () => { + const result = await processFixture('directives'); + expect(result).toMatchSnapshot(); + }); +}); diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts new file mode 100644 index 000000000000..c0845c49638d --- /dev/null +++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts @@ -0,0 +1,74 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import visit from 'unist-util-visit'; +// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721 +import type {Transformer, Processor, Parent} from 'unified'; + +import type { + ContainerDirective, + LeafDirective, + TextDirective, + // @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721 +} from 'mdast-util-directive'; + +// TODO as of April 2023, no way to import/re-export this ESM type easily :/ +// This might change soon, likely after TS 5.2 +// See https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1517839391 +// import type {Plugin} from 'unified'; +type Plugin = any; // TODO fix this asap + +const plugin: Plugin = function plugin(this: Processor): Transformer { + return (root) => { + const unusedDirectives: Array<{ + name: string; + type: string; + }> = []; + const directiveTypes = [ + 'containerDirective', + 'leafDirective', + 'textDirective', + ]; + + const directiveVisitor = ( + node: ContainerDirective | LeafDirective | TextDirective, + ) => { + if (directiveTypes.includes(node.type)) { + unusedDirectives.push({ + name: node.name, + type: node.type, + // start: node.position.start.line, + // path: ` ${filePath}:${node.position.start.line}:${node.position.start.column}`, + }); + } + }; + + // const directiveVisitor = ( + // node: ContainerDirective | LeafDirective | TextDirective, + // ) => { + // // Convert the directive to plain text and add it to the + // // unusedDirectives array + + // unusedDirectives.push(directiveText); + + // // Remove the directive from the tree + // if (parent) { + // const index = parent.children.indexOf(node); + // if (index !== -1) { + // parent.children.splice(index, 1); + // } + // } + // }; + + visitTest directives
- +Text
+Text:base
Text: base
::::info Weather
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
index c0845c49638d..391c7189fdbb 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
@@ -8,13 +8,6 @@ import visit from 'unist-util-visit';
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
import type {Transformer, Processor, Parent} from 'unified';
-import type {
- ContainerDirective,
- LeafDirective,
- TextDirective,
- // @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
-} from 'mdast-util-directive';
-
// TODO as of April 2023, no way to import/re-export this ESM type easily :/
// This might change soon, likely after TS 5.2
// See https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1517839391
@@ -22,9 +15,9 @@ import type {
type Plugin = any; // TODO fix this asap
const plugin: Plugin = function plugin(this: Processor): Transformer {
- return (root) => {
+ return (tree) => {
const unusedDirectives: Array<{
- name: string;
+ name: string | null;
type: string;
}> = [];
const directiveTypes = [
@@ -33,9 +26,7 @@ const plugin: Plugin = function plugin(this: Processor): Transformer {
'textDirective',
];
- const directiveVisitor = (
- node: ContainerDirective | LeafDirective | TextDirective,
- ) => {
+ const directiveVisitor = (node: any) => {
if (directiveTypes.includes(node.type)) {
unusedDirectives.push({
name: node.name,
@@ -43,31 +34,18 @@ const plugin: Plugin = function plugin(this: Processor): Transformer {
// start: node.position.start.line,
// path: ` ${filePath}:${node.position.start.line}:${node.position.start.column}`,
});
+
+ if (node.children) {
+ node.children.forEach((child: any) => directiveVisitor(child));
+ }
}
};
- // const directiveVisitor = (
- // node: ContainerDirective | LeafDirective | TextDirective,
- // ) => {
- // // Convert the directive to plain text and add it to the
- // // unusedDirectives array
-
- // unusedDirectives.push(directiveText);
-
- // // Remove the directive from the tree
- // if (parent) {
- // const index = parent.children.indexOf(node);
- // if (index !== -1) {
- // parent.children.splice(index, 1);
- // }
- // }
- // };
-
- visit Test directives
Text
-Text:base
-Text: base
- -::::info Weather -On nice days, you can enjoy skiing in the mountains.
:::danger Storms -Take care of snowstorms...
::::
" +"Take care of snowstorms...
unused directive content
:::NotAContainerDirective with a phrase after
+:::
+Phrase before :::NotAContainerDirective
+:::
" +`; + +exports[`directives remark plugin default behavior for custom keyword 2`] = ` +[ + [ + "Unused Directives found: ", + [ + { + "name": "danger", + "type": "containerDirective", + }, + { + "name": "unusedDirective", + "type": "containerDirective", + }, + ], + ], +] `; diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts index 205ecf6aa058..612dfccb6e3e 100644 --- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts +++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts @@ -9,8 +9,8 @@ import path from 'path'; import remark2rehype from 'remark-rehype'; import stringify from 'rehype-stringify'; import vfile from 'to-vfile'; -import preprocessor from '../../../preprocessor'; import plugin from '../index'; +import admonition from '../../admonitions'; const processFixture = async (name: string) => { const {remark} = await import('remark'); @@ -18,32 +18,28 @@ const processFixture = async (name: string) => { const filePath = path.join(__dirname, '__fixtures__', `${name}.md`); const file = await vfile.read(filePath); - const fileContentPreprocessed = preprocessor({ - fileContent: file.toString(), - filePath, - markdownConfig: { - mermaid: false, - mdx1Compat: { - admonitions: false, - comments: false, - headingIds: false, - }, - }, - }); const result = await remark() .use(directives) + .use(admonition) .use(plugin) .use(remark2rehype) .use(stringify) - .process(fileContentPreprocessed); + .process(file); return result.value; }; describe('directives remark plugin', () => { it('default behavior for custom keyword', async () => { - const result = await processFixture('directives'); + const consoleMock = jest + .spyOn(console, 'warn') + .mockImplementation(() => {}); + + const result = await processFixture('containerDirectives'); + expect(result).toMatchSnapshot(); + + expect(consoleMock.mock.calls).toMatchSnapshot(); }); }); diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts index 391c7189fdbb..46e22cf66aab 100644 --- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts +++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts @@ -7,6 +7,12 @@ import visit from 'unist-util-visit'; // @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721 import type {Transformer, Processor, Parent} from 'unified'; +// import type { +// ContainerDirective, +// LeafDirective, +// TextDirective, +// // @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721 +// } from 'mdast-util-directive'; // TODO as of April 2023, no way to import/re-export this ESM type easily :/ // This might change soon, likely after TS 5.2 @@ -20,6 +26,7 @@ const plugin: Plugin = function plugin(this: Processor): Transformer { name: string | null; type: string; }> = []; + const directiveTypes = [ 'containerDirective', 'leafDirective', @@ -35,16 +42,17 @@ const plugin: Plugin = function plugin(this: Processor): Transformer { // path: ` ${filePath}:${node.position.start.line}:${node.position.start.column}`, }); - if (node.children) { - node.children.forEach((child: any) => directiveVisitor(child)); - } + // if (node.children) { + // node.children.forEach((child: any) => directiveVisitor(child)); + // } } }; - visitTake care of snowstorms...
unused directive content
:::NotAContainerDirective with a phrase after
@@ -9,10 +9,41 @@ exports[`directives remark plugin default behavior for custom keyword 1`] = `:::
" `; -exports[`directives remark plugin default behavior for custom keyword 2`] = ` +exports[`directives remark plugin default behavior for container directives 2`] = ` [ [ "[WARNING] We found a potential error in your documentation unusedDirective "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/containerDirectives.md":7:1", ], ] `; + +exports[`directives remark plugin default behavior for leaf directives 1`] = ` +" +Leaf directive in a phrase ::NotALeafDirective
+::NotALeafDirective with a phrase after
" +`; + +exports[`directives remark plugin default behavior for leaf directives 2`] = ` +[ + [ + "[WARNING] We found a potential error in your documentation unusedLeafDirective "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/leafDirectives.md":1:1", + ], +] +`; + +exports[`directives remark plugin default behavior for text directives 1`] = ` +"Simple: textDirective1
+Simple: textDirective1
+
+Simple
+Simple:textDirective1
+
"
+`;
+
+exports[`directives remark plugin default behavior for text directives 2`] = `
+[
+ [
+ "[WARNING] We found a potential error in your documentation textDirective2 "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/textDirectives.md":7:7",
+ ],
+]
+`;
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts
index 612dfccb6e3e..815a84fefd94 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts
@@ -31,15 +31,37 @@ const processFixture = async (name: string) => {
};
describe('directives remark plugin', () => {
- it('default behavior for custom keyword', async () => {
- const consoleMock = jest
- .spyOn(console, 'warn')
- .mockImplementation(() => {});
+ let consoleMock;
+ beforeEach(() => {
+ consoleMock = jest.spyOn(console, 'warn').mockImplementation(() => {});
+ });
+
+ afterEach(() => {
+ consoleMock.mockRestore();
+ });
+
+ it('default behavior for container directives', async () => {
const result = await processFixture('containerDirectives');
expect(result).toMatchSnapshot();
expect(consoleMock.mock.calls).toMatchSnapshot();
});
+
+ it('default behavior for leaf directives', async () => {
+ const result = await processFixture('leafDirectives');
+
+ expect(result).toMatchSnapshot();
+
+ expect(consoleMock.mock.calls).toMatchSnapshot();
+ });
+
+ it('default behavior for text directives', async () => {
+ const result = await processFixture('textDirectives');
+
+ expect(result).toMatchSnapshot();
+
+ expect(consoleMock.mock.calls).toMatchSnapshot();
+ });
});
From 6a0337aea925f555816abd02cf5e335bb338c299 Mon Sep 17 00:00:00 2001
From: ozakione <29860391+OzakIOne@users.noreply.github.com>
Date: Fri, 13 Oct 2023 14:00:36 +0200
Subject: [PATCH 08/24] fix: include lines in path
---
.../src/remark/unusedDirectives/index.ts | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
index f8097089270a..94650572e46f 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
@@ -68,7 +68,9 @@ const plugin: Plugin = function plugin(this: Processor): Transformer {
const customPath = posixPath(path.relative(process.cwd(), file.path));
- return logger.interpolate`We found a potential error in your documentation name=${unusedDirective.name} path=${customPath}:${positionMessage}`;
+ return logger.interpolate`We found a potential error in your documentation name=${
+ unusedDirective.name
+ } path=${`${customPath}:${positionMessage}`}`;
})
.join('\n');
logger.warn(warningMessage);
From e4e72550991714cd54d142f6253a52a8864a6ab2 Mon Sep 17 00:00:00 2001
From: sebastienlorber Take care of snowstorms...
unused directive content
:::NotAContainerDirective with a phrase after
@@ -9,29 +9,29 @@ exports[`directives remark plugin default behavior for container directives 1`]:::
" `; -exports[`directives remark plugin default behavior for container directives 2`] = ` +exports[`directives remark plugin - client compiler default behavior for container directives 2`] = ` [ [ - "[WARNING] We found a potential error in your documentation unusedDirective "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/containerDirectives.md":7:1", + "[WARNING] We found a potential error in your documentation unusedDirective "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/containerDirectives.md:7:1"", ], ] `; -exports[`directives remark plugin default behavior for leaf directives 1`] = ` +exports[`directives remark plugin - client compiler default behavior for leaf directives 1`] = ` "Leaf directive in a phrase ::NotALeafDirective
::NotALeafDirective with a phrase after
" `; -exports[`directives remark plugin default behavior for leaf directives 2`] = ` +exports[`directives remark plugin - client compiler default behavior for leaf directives 2`] = ` [ [ - "[WARNING] We found a potential error in your documentation unusedLeafDirective "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/leafDirectives.md":1:1", + "[WARNING] We found a potential error in your documentation unusedLeafDirective "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/leafDirectives.md:1:1"", ], ] `; -exports[`directives remark plugin default behavior for text directives 1`] = ` +exports[`directives remark plugin - client compiler default behavior for text directives 1`] = ` "Simple: textDirective1
Simple: textDirective1
@@ -40,10 +40,34 @@ exports[`directives remark plugin default behavior for text directives 1`] = `
"
`;
-exports[`directives remark plugin default behavior for text directives 2`] = `
+exports[`directives remark plugin - client compiler default behavior for text directives 2`] = `
[
[
- "[WARNING] We found a potential error in your documentation textDirective2 "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/textDirectives.md":7:7",
+ "[WARNING] We found a potential error in your documentation textDirective2 "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/textDirectives.md:7:7"",
],
]
`;
+
+exports[`directives remark plugin - server compiler default behavior for container directives 1`] = `
+"Take care of snowstorms...
unused directive content
:::NotAContainerDirective with a phrase after
+:::
+Phrase before :::NotAContainerDirective
+:::
" +`; + +exports[`directives remark plugin - server compiler default behavior for leaf directives 1`] = ` +" +Leaf directive in a phrase ::NotALeafDirective
+::NotALeafDirective with a phrase after
" +`; + +exports[`directives remark plugin - server compiler default behavior for text directives 1`] = ` +"Simple: textDirective1
+Simple: textDirective1
+
+Simple
+Simple:textDirective1
+
"
+`;
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts
index 815a84fefd94..5e0d3ea7dd9b 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts
@@ -11,13 +11,18 @@ import stringify from 'rehype-stringify';
import vfile from 'to-vfile';
import plugin from '../index';
import admonition from '../../admonitions';
+import type {WebpackCompilerName} from '@docusaurus/utils';
-const processFixture = async (name: string) => {
+const processFixture = async (
+ name: string,
+ {compilerName}: {compilerName: WebpackCompilerName},
+) => {
const {remark} = await import('remark');
const {default: directives} = await import('remark-directive');
const filePath = path.join(__dirname, '__fixtures__', `${name}.md`);
const file = await vfile.read(filePath);
+ file.data.compilerName = compilerName;
const result = await remark()
.use(directives)
@@ -30,38 +35,55 @@ const processFixture = async (name: string) => {
return result.value;
};
-describe('directives remark plugin', () => {
- let consoleMock;
+describe('directives remark plugin - client compiler', () => {
+ const consoleMock = jest.spyOn(console, 'warn').mockImplementation(() => {});
+ beforeEach(() => jest.clearAllMocks());
- beforeEach(() => {
- consoleMock = jest.spyOn(console, 'warn').mockImplementation(() => {});
- });
-
- afterEach(() => {
- consoleMock.mockRestore();
- });
+ const options = {compilerName: 'client'} as const;
it('default behavior for container directives', async () => {
- const result = await processFixture('containerDirectives');
-
+ const result = await processFixture('containerDirectives', options);
expect(result).toMatchSnapshot();
-
+ expect(consoleMock).toHaveBeenCalledTimes(1);
expect(consoleMock.mock.calls).toMatchSnapshot();
});
it('default behavior for leaf directives', async () => {
- const result = await processFixture('leafDirectives');
-
+ const result = await processFixture('leafDirectives', options);
expect(result).toMatchSnapshot();
-
+ expect(consoleMock).toHaveBeenCalledTimes(1);
expect(consoleMock.mock.calls).toMatchSnapshot();
});
it('default behavior for text directives', async () => {
- const result = await processFixture('textDirectives');
+ const result = await processFixture('textDirectives', options);
+ expect(result).toMatchSnapshot();
+ expect(consoleMock).toHaveBeenCalledTimes(1);
+ expect(consoleMock.mock.calls).toMatchSnapshot();
+ });
+});
+describe('directives remark plugin - server compiler', () => {
+ const consoleMock = jest.spyOn(console, 'warn').mockImplementation(() => {});
+ beforeEach(() => jest.clearAllMocks());
+
+ const options = {compilerName: 'server'} as const;
+
+ it('default behavior for container directives', async () => {
+ const result = await processFixture('containerDirectives', options);
expect(result).toMatchSnapshot();
+ expect(consoleMock).toHaveBeenCalledTimes(0);
+ });
- expect(consoleMock.mock.calls).toMatchSnapshot();
+ it('default behavior for leaf directives', async () => {
+ const result = await processFixture('leafDirectives', options);
+ expect(result).toMatchSnapshot();
+ expect(consoleMock).toHaveBeenCalledTimes(0);
+ });
+
+ it('default behavior for text directives', async () => {
+ const result = await processFixture('textDirectives', options);
+ expect(result).toMatchSnapshot();
+ expect(consoleMock).toHaveBeenCalledTimes(0);
});
});
From 1b59e60dd909fbdc9412c44a927dcf4a8c999753 Mon Sep 17 00:00:00 2001
From: ozakione <29860391+OzakIOne@users.noreply.github.com>
Date: Fri, 13 Oct 2023 19:05:24 +0200
Subject: [PATCH 10/24] wip: improve log messages
---
.../__snapshots__/index.test.ts.snap | 12 ++++++--
.../src/remark/unusedDirectives/index.ts | 28 ++++++++++++++-----
2 files changed, 30 insertions(+), 10 deletions(-)
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap
index d6c4cea39113..d8f131bc48cb 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap
@@ -12,7 +12,9 @@ exports[`directives remark plugin - client compiler default behavior for contain
exports[`directives remark plugin - client compiler default behavior for container directives 2`] = `
[
[
- "[WARNING] We found a potential error in your documentation unusedDirective "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/containerDirectives.md:7:1"",
+ "[WARNING] Docusaurus found 1 unused Markdown directives in file packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/containerDirectives.md
+- 7:1 :::unusedDirective
+Your content might render in an unexpected way. Visit https://github.com/facebook/docusaurus/pull/9394 to find out why and how to fix it.",
],
]
`;
@@ -26,7 +28,9 @@ exports[`directives remark plugin - client compiler default behavior for leaf di
exports[`directives remark plugin - client compiler default behavior for leaf directives 2`] = `
[
[
- "[WARNING] We found a potential error in your documentation unusedLeafDirective "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/leafDirectives.md:1:1"",
+ "[WARNING] Docusaurus found 1 unused Markdown directives in file packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/leafDirectives.md
+- 1:1 ::unusedLeafDirective
+Your content might render in an unexpected way. Visit https://github.com/facebook/docusaurus/pull/9394 to find out why and how to fix it.",
],
]
`;
@@ -43,7 +47,9 @@ exports[`directives remark plugin - client compiler default behavior for text di
exports[`directives remark plugin - client compiler default behavior for text directives 2`] = `
[
[
- "[WARNING] We found a potential error in your documentation textDirective2 "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/textDirectives.md:7:7"",
+ "[WARNING] Docusaurus found 1 unused Markdown directives in file packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/textDirectives.md
+- 7:7 :textDirective2
+Your content might render in an unexpected way. Visit https://github.com/facebook/docusaurus/pull/9394 to find out why and how to fix it.",
],
]
`;
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
index 94650572e46f..cbd515629334 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
@@ -60,20 +60,34 @@ const plugin: Plugin = function plugin(this: Processor): Transformer {
});
if (unusedDirectives.length > 0) {
- const warningMessage = unusedDirectives
+ const supportUrl = 'https://github.com/facebook/docusaurus/pull/9394';
+ const customPath = posixPath(path.relative(process.cwd(), file.path));
+ const warningTitle = logger.interpolate`Docusaurus found ${unusedDirectives.length} unused Markdown directives in file path=${customPath}`;
+ const customSupportUrl = logger.interpolate`url=${supportUrl}`;
+
+ const warningMessages = unusedDirectives
.map((unusedDirective) => {
+ let customDirectiveName = unusedDirective.name;
+
+ if (unusedDirective.type === 'containerDirective') {
+ customDirectiveName = `:::${unusedDirective.name}`;
+ } else if (unusedDirective.type === 'leafDirective') {
+ customDirectiveName = `::${unusedDirective.name}`;
+ } else if (unusedDirective.type === 'textDirective') {
+ customDirectiveName = `:${unusedDirective.name}`;
+ }
+
const positionMessage = unusedDirective.position
? logger.interpolate`number=${unusedDirective.position.line}:number=${unusedDirective.position.column}`
: '';
- const customPath = posixPath(path.relative(process.cwd(), file.path));
-
- return logger.interpolate`We found a potential error in your documentation name=${
- unusedDirective.name
- } path=${`${customPath}:${positionMessage}`}`;
+ return `- ${positionMessage} ${customDirectiveName} `;
})
.join('\n');
- logger.warn(warningMessage);
+
+ logger.warn(`${warningTitle}
+${warningMessages}
+Your content might render in an unexpected way. Visit ${customSupportUrl} to find out why and how to fix it.`);
}
};
};
From 59cb00ff810e0c952a4c50a2f428f7555c1471bb Mon Sep 17 00:00:00 2001
From: sebastienlorber Take care of snowstorms...
unused directive content
:::NotAContainerDirective with a phrase after
@@ -9,52 +19,46 @@ exports[`directives remark plugin - client compiler default behavior for contain:::
" `; -exports[`directives remark plugin - client compiler default behavior for container directives 2`] = ` +exports[`directives remark plugin - client compiler default behavior for leaf directives: console 1`] = ` [ [ - "[WARNING] Docusaurus found 1 unused Markdown directives in file packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/containerDirectives.md -- 7:1 :::unusedDirective + "[WARNING] Docusaurus found 1 unused Markdown directives in file "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/leafDirectives.md" +- 1:1 ::unusedLeafDirective Your content might render in an unexpected way. Visit https://github.com/facebook/docusaurus/pull/9394 to find out why and how to fix it.", ], ] `; -exports[`directives remark plugin - client compiler default behavior for leaf directives 1`] = ` +exports[`directives remark plugin - client compiler default behavior for leaf directives: result 1`] = ` "Leaf directive in a phrase ::NotALeafDirective
::NotALeafDirective with a phrase after
" `; -exports[`directives remark plugin - client compiler default behavior for leaf directives 2`] = ` +exports[`directives remark plugin - client compiler default behavior for text directives: console 1`] = ` [ [ - "[WARNING] Docusaurus found 1 unused Markdown directives in file packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/leafDirectives.md -- 1:1 ::unusedLeafDirective + "[WARNING] Docusaurus found 3 unused Markdown directives in file "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/textDirectives.md" +- 7:7 :textDirective2 +- 9:7 :textDirective3 +- 11:7 :textDirective4 Your content might render in an unexpected way. Visit https://github.com/facebook/docusaurus/pull/9394 to find out why and how to fix it.", ], ] `; -exports[`directives remark plugin - client compiler default behavior for text directives 1`] = ` +exports[`directives remark plugin - client compiler default behavior for text directives: result 1`] = ` "Simple: textDirective1
Simple: textDirective1
Simple
+Simple
Simple
Simple:textDirective1
"
`;
-exports[`directives remark plugin - client compiler default behavior for text directives 2`] = `
-[
- [
- "[WARNING] Docusaurus found 1 unused Markdown directives in file packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/textDirectives.md
-- 7:7 :textDirective2
-Your content might render in an unexpected way. Visit https://github.com/facebook/docusaurus/pull/9394 to find out why and how to fix it.",
- ],
-]
-`;
-
-exports[`directives remark plugin - server compiler default behavior for container directives 1`] = `
+exports[`directives remark plugin - server compiler default behavior for container directives: result 1`] = `
"Take care of snowstorms...
unused directive content
:::NotAContainerDirective with a phrase after
@@ -63,17 +67,19 @@ exports[`directives remark plugin - server compiler default behavior for contain:::
" `; -exports[`directives remark plugin - server compiler default behavior for leaf directives 1`] = ` +exports[`directives remark plugin - server compiler default behavior for leaf directives: result 1`] = ` "Leaf directive in a phrase ::NotALeafDirective
::NotALeafDirective with a phrase after
" `; -exports[`directives remark plugin - server compiler default behavior for text directives 1`] = ` +exports[`directives remark plugin - server compiler default behavior for text directives: result 1`] = ` "Simple: textDirective1
Simple: textDirective1
Simple
+Simple
Simple
Simple:textDirective1
"
`;
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts
index 5e0d3ea7dd9b..32ab6866afe3 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts
@@ -43,23 +43,23 @@ describe('directives remark plugin - client compiler', () => {
it('default behavior for container directives', async () => {
const result = await processFixture('containerDirectives', options);
- expect(result).toMatchSnapshot();
+ expect(result).toMatchSnapshot('result');
expect(consoleMock).toHaveBeenCalledTimes(1);
- expect(consoleMock.mock.calls).toMatchSnapshot();
+ expect(consoleMock.mock.calls).toMatchSnapshot('console');
});
it('default behavior for leaf directives', async () => {
const result = await processFixture('leafDirectives', options);
- expect(result).toMatchSnapshot();
+ expect(result).toMatchSnapshot('result');
expect(consoleMock).toHaveBeenCalledTimes(1);
- expect(consoleMock.mock.calls).toMatchSnapshot();
+ expect(consoleMock.mock.calls).toMatchSnapshot('console');
});
it('default behavior for text directives', async () => {
const result = await processFixture('textDirectives', options);
- expect(result).toMatchSnapshot();
+ expect(result).toMatchSnapshot('result');
expect(consoleMock).toHaveBeenCalledTimes(1);
- expect(consoleMock.mock.calls).toMatchSnapshot();
+ expect(consoleMock.mock.calls).toMatchSnapshot('console');
});
});
@@ -71,19 +71,19 @@ describe('directives remark plugin - server compiler', () => {
it('default behavior for container directives', async () => {
const result = await processFixture('containerDirectives', options);
- expect(result).toMatchSnapshot();
+ expect(result).toMatchSnapshot('result');
expect(consoleMock).toHaveBeenCalledTimes(0);
});
it('default behavior for leaf directives', async () => {
const result = await processFixture('leafDirectives', options);
- expect(result).toMatchSnapshot();
+ expect(result).toMatchSnapshot('result');
expect(consoleMock).toHaveBeenCalledTimes(0);
});
it('default behavior for text directives', async () => {
const result = await processFixture('textDirectives', options);
- expect(result).toMatchSnapshot();
+ expect(result).toMatchSnapshot('result');
expect(consoleMock).toHaveBeenCalledTimes(0);
});
});
From 61b41ae5b912164a40ea60041f82b52f797e04e0 Mon Sep 17 00:00:00 2001
From: sebastienlorber Simple
Simple
Simple
+Simple
Simple:textDirective1
"
`;
@@ -80,6 +82,7 @@ exports[`directives remark plugin - server compiler default behavior for text di
Simple
Simple
Simple
+Simple
Simple:textDirective1
"
`;
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
index adec94e70701..c2d868faa420 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
@@ -57,7 +57,7 @@ function formatUnusedDirectiveMessage(directive: Directive) {
const name = formatDirectiveName(directive);
const position = formatDirectivePosition(directive);
- return `- ${position ?? ''} ${name} `;
+ return `- ${name} ${position ? `(${position})` : ''}`;
}
function formatUnusedDirectivesMessage({
From 23f6cb92507493a96037c0d3da048192e69479ec Mon Sep 17 00:00:00 2001
From: sebastienlorber Simple: textDirective1
-Simple: textDirective1
+Simple: textDirectiveCode
Simple
Simple
label
Simple
Simple
-Simple:textDirective1
+Simple:textDirectiveCode
"
`;
@@ -77,12 +77,12 @@ exports[`directives remark plugin - server compiler default behavior for leaf di
exports[`directives remark plugin - server compiler default behavior for text directives: result 1`] = `
"Simple: textDirective1
-Simple: textDirective1
+Simple: textDirectiveCode
Simple
Simple
label
Simple
Simple
-Simple:textDirective1
+Simple:textDirectiveCode
"
`;
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
index c2d868faa420..eb2556ed774e 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
@@ -13,6 +13,7 @@ import {posixPath} from '@docusaurus/utils';
import type {Transformer, Processor, Parent} from 'unified';
import type {
Directive,
+ TextDirective,
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
} from 'mdast-util-directive';
@@ -30,7 +31,7 @@ const directiveTypes: DirectiveType[] = [
'textDirective',
];
-const directivePrefixMap: { [key: DirectiveType]: string } = {
+const directivePrefixMap: {[key: DirectiveType]: string} = {
textDirective: ':',
leafDirective: '::',
containerDirective: ':::',
@@ -80,6 +81,24 @@ ${warningMessages}
Your content might render in an unexpected way. Visit ${customSupportUrl} to find out why and how to fix it.`;
}
+function isTextDirective(directive: Directive): directive is TextDirective {
+ return directive.type === 'textDirective';
+}
+
+// A simple text directive is one without any label/props
+function isSimpleTextDirective(
+ directive: Directive,
+): directive is TextDirective {
+ if (isTextDirective(directive)) {
+ // Attributes in MDAST = Directive props
+ const hasAttributes = Object.keys(directive.attributes ?? {}).length > 0;
+ // Children in MDAST = Directive label
+ const hasChildren = directive.children.length > 0;
+ return hasAttributes || hasChildren;
+ }
+ return false;
+}
+
const plugin: Plugin = function plugin(this: Processor): Transformer {
return (tree, file) => {
// We only enable these warnings for the client compiler
@@ -95,7 +114,12 @@ const plugin: Plugin = function plugin(this: Processor): Transformer {
// If directive data is set (notably hName/hProperties set by admonitions)
// this usually means the directive has been handled by another plugin
if (!directive.data) {
- unusedDirectives.push(directive);
+ if (isSimpleTextDirective(directive)) {
+ // TODO !
+ unusedDirectives.push(directive);
+ } else {
+ unusedDirectives.push(directive);
+ }
}
});
From 55a0abee65074b1a91fcfec4c71be85cddd6f5b4 Mon Sep 17 00:00:00 2001
From: sebastienlorber
Date: Tue, 24 Oct 2023 10:58:13 +0200
Subject: [PATCH 18/24] Implement unused simple text directive re-serialization
---
.../__snapshots__/index.test.ts.snap | 8 +++----
.../src/remark/unusedDirectives/index.ts | 22 ++++++++++++++----
.../src/remark/utils/index.ts | 23 ++++++++++++++++++-
3 files changed, 43 insertions(+), 10 deletions(-)
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap
index 20cec10143c7..14b8183e76de 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap
@@ -38,11 +38,9 @@ exports[`directives remark plugin - client compiler default behavior for leaf di
exports[`directives remark plugin - client compiler default behavior for text directives: console 1`] = `
[
[
- "[WARNING] Docusaurus found 4 unused Markdown directives in file "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/textDirectives.md"
-- :textDirective2 (7:7)
+ "[WARNING] Docusaurus found 2 unused Markdown directives in file "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/textDirectives.md"
- :textDirective3 (9:7)
- :textDirective4 (11:7)
-- :textDirective5 (13:7)
Your content might render in an unexpected way. Visit https://github.com/facebook/docusaurus/pull/9394 to find out why and how to fix it.",
],
]
@@ -52,10 +50,10 @@ exports[`directives remark plugin - client compiler default behavior for text di
"Simple: textDirective1
Simple: textDirectiveCode
-Simple
+Simple:textDirective2
Simple
label
Simple
-Simple
+Simple:textDirective5
Simple:textDirectiveCode
"
`;
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
index eb2556ed774e..435d9b75f394 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
@@ -9,6 +9,8 @@ import process from 'process';
import visit from 'unist-util-visit';
import logger from '@docusaurus/logger';
import {posixPath} from '@docusaurus/utils';
+import {transformNode} from '../utils';
+
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
import type {Transformer, Processor, Parent} from 'unified';
import type {
@@ -94,11 +96,24 @@ function isSimpleTextDirective(
const hasAttributes = Object.keys(directive.attributes ?? {}).length > 0;
// Children in MDAST = Directive label
const hasChildren = directive.children.length > 0;
- return hasAttributes || hasChildren;
+ return !hasAttributes && !hasChildren;
}
return false;
}
+function transformSimpleTextDirectiveToString(textDirective: Directive) {
+ transformNode(textDirective, {
+ type: 'text',
+ value: `:${textDirective.name}`, // We ignore label/props on purpose here
+ });
+}
+
+function isUnusedDirective(directive: Directive) {
+ // If directive data is set (notably hName/hProperties set by admonitions)
+ // this usually means the directive has been handled by another plugin
+ return !directive.data;
+}
+
const plugin: Plugin = function plugin(this: Processor): Transformer {
return (tree, file) => {
// We only enable these warnings for the client compiler
@@ -113,10 +128,9 @@ const plugin: Plugin = function plugin(this: Processor): Transformer {
visit(tree, directiveTypes, (directive: Directive) => {
// If directive data is set (notably hName/hProperties set by admonitions)
// this usually means the directive has been handled by another plugin
- if (!directive.data) {
+ if (isUnusedDirective(directive)) {
if (isSimpleTextDirective(directive)) {
- // TODO !
- unusedDirectives.push(directive);
+ transformSimpleTextDirectiveToString(directive);
} else {
unusedDirectives.push(directive);
}
diff --git a/packages/docusaurus-mdx-loader/src/remark/utils/index.ts b/packages/docusaurus-mdx-loader/src/remark/utils/index.ts
index 46e959176239..3b29be807e2d 100644
--- a/packages/docusaurus-mdx-loader/src/remark/utils/index.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/utils/index.ts
@@ -6,7 +6,7 @@
*/
import escapeHtml from 'escape-html';
-import type {Parent} from 'unist';
+import type {Parent, Node} from 'unist';
import type {PhrasingContent, Heading} from 'mdast';
import type {
MdxJsxAttribute,
@@ -15,6 +15,27 @@ import type {
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
} from 'mdast-util-mdx';
+/**
+ * Util to transform one node type to another node type
+ * The input node is mutated in place
+ * @param node the node to mutate
+ * @param newNode what the original node should become become
+ */
+export function transformNode(
+ node: Node,
+ newNode: NewNode,
+): NewNode {
+ Object.keys(node).forEach((key) => {
+ // @ts-expect-error: unsafe but ok
+ delete node[key];
+ });
+ Object.keys(newNode).forEach((key) => {
+ // @ts-expect-error: unsafe but ok
+ node[key] = newNode[key];
+ });
+ return node as NewNode;
+}
+
export function stringifyContent(
node: Parent,
toString: (param: unknown) => string, // TODO weird but works
From 5fb34aeea8374f542f251fa3a039bec1ebac0fde Mon Sep 17 00:00:00 2001
From: sebastienlorber
Date: Tue, 24 Oct 2023 11:07:18 +0200
Subject: [PATCH 19/24] use transformNode everywhere
---
.../src/remark/mermaid/index.ts | 6 ++++--
.../src/remark/transformImage/index.ts | 16 +++++++---------
.../src/remark/transformLinks/index.ts | 16 +++++++---------
.../src/remark/unusedDirectives/index.ts | 3 ++-
4 files changed, 20 insertions(+), 21 deletions(-)
diff --git a/packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts b/packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts
index 7947d3387e1f..7a5eac045601 100644
--- a/packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/mermaid/index.ts
@@ -6,6 +6,8 @@
*/
import visit from 'unist-util-visit';
+import {transformNode} from '../utils';
+
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
import type {Transformer} from 'unified';
import type {Code} from 'mdast';
@@ -16,10 +18,10 @@ import type {Code} from 'mdast';
// by theme-mermaid itself
export default function plugin(): Transformer {
return (root) => {
- visit(root, 'code', (node: Code, index, parent) => {
+ visit(root, 'code', (node: Code) => {
if (node.lang === 'mermaid') {
// TODO migrate to mdxJsxFlowElement? cf admonitions
- parent!.children.splice(index, 1, {
+ transformNode(node, {
type: 'mermaidCodeBlock',
data: {
hName: 'mermaid',
diff --git a/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts b/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts
index 5bd9c1d9a991..956de8a8df47 100644
--- a/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/transformImage/index.ts
@@ -20,7 +20,7 @@ import visit from 'unist-util-visit';
import escapeHtml from 'escape-html';
import sizeOf from 'image-size';
import logger from '@docusaurus/logger';
-import {assetRequireAttributeValue} from '../utils';
+import {assetRequireAttributeValue, transformNode} from '../utils';
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
import type {Transformer} from 'unified';
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
@@ -110,14 +110,12 @@ ${(err as Error).message}`;
}
}
- Object.keys(jsxNode).forEach(
- (key) => delete jsxNode[key as keyof typeof jsxNode],
- );
-
- jsxNode.type = 'mdxJsxTextElement';
- jsxNode.name = 'img';
- jsxNode.attributes = attributes;
- jsxNode.children = [];
+ transformNode(jsxNode, {
+ type: 'mdxJsxTextElement',
+ name: 'img',
+ attributes,
+ children: [],
+ });
}
async function ensureImageFileExist(imagePath: string, sourceFilePath: string) {
diff --git a/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.ts b/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.ts
index 71086023345c..bddf42613f4f 100644
--- a/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/transformLinks/index.ts
@@ -17,7 +17,7 @@ import {
} from '@docusaurus/utils';
import visit from 'unist-util-visit';
import escapeHtml from 'escape-html';
-import {assetRequireAttributeValue} from '../utils';
+import {assetRequireAttributeValue, transformNode} from '../utils';
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
import type {Transformer} from 'unified';
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
@@ -90,14 +90,12 @@ async function toAssetRequireNode(
const {children} = node;
- Object.keys(jsxNode).forEach(
- (key) => delete jsxNode[key as keyof typeof jsxNode],
- );
-
- jsxNode.type = 'mdxJsxTextElement';
- jsxNode.name = 'a';
- jsxNode.attributes = attributes;
- jsxNode.children = children;
+ transformNode(jsxNode, {
+ type: 'mdxJsxTextElement',
+ name: 'a',
+ attributes,
+ children,
+ });
}
async function ensureAssetFileExist(assetPath: string, sourceFilePath: string) {
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
index 435d9b75f394..f2376a2defec 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
@@ -93,7 +93,8 @@ function isSimpleTextDirective(
): directive is TextDirective {
if (isTextDirective(directive)) {
// Attributes in MDAST = Directive props
- const hasAttributes = Object.keys(directive.attributes ?? {}).length > 0;
+ const hasAttributes =
+ directive.attributes && Object.keys(directive.attributes).length > 0;
// Children in MDAST = Directive label
const hasChildren = directive.children.length > 0;
return !hasAttributes && !hasChildren;
From 764e9abfcdfbe2b11ae0d8998d023100ef7d7494 Mon Sep 17 00:00:00 2001
From: sebastienlorber
Date: Tue, 24 Oct 2023 11:09:54 +0200
Subject: [PATCH 20/24] eslint
---
.eslintrc.js | 2 +-
.../docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/.eslintrc.js b/.eslintrc.js
index 8dc4c5101e99..6a0b15228fd0 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -286,7 +286,7 @@ module.exports = {
],
'import/prefer-default-export': OFF,
- 'jest/consistent-test-it': OFF,
+ 'jest/consistent-test-it': WARNING,
'jest/expect-expect': OFF,
'jest/no-large-snapshots': [
WARNING,
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
index f2376a2defec..d2db6e176241 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
@@ -33,7 +33,8 @@ const directiveTypes: DirectiveType[] = [
'textDirective',
];
-const directivePrefixMap: {[key: DirectiveType]: string} = {
+// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style
+const directivePrefixMap: Record = {
textDirective: ':',
leafDirective: '::',
containerDirective: ':::',
From bfa8a90776bdaac75cb89691e17a228ab65c6bcb Mon Sep 17 00:00:00 2001
From: sebastienlorber
Date: Tue, 24 Oct 2023 11:11:42 +0200
Subject: [PATCH 21/24] eslint
---
.../docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
index d2db6e176241..480714df88df 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
@@ -33,8 +33,7 @@ const directiveTypes: DirectiveType[] = [
'textDirective',
];
-// eslint-disable-next-line @typescript-eslint/consistent-indexed-object-style
-const directivePrefixMap: Record = {
+const directivePrefixMap: {[key in DirectiveType]: string} = {
textDirective: ':',
leafDirective: '::',
containerDirective: ':::',
From 99f83b244d2f18d043554e48a1c1207990f9e89e Mon Sep 17 00:00:00 2001
From: sebastienlorber
Date: Tue, 24 Oct 2023 11:22:53 +0200
Subject: [PATCH 22/24] fix bug + add client/server output mismatch tests
---
.../__snapshots__/index.test.ts.snap | 4 +--
.../unusedDirectives/__tests__/index.test.ts | 22 +++++++++++++
.../src/remark/unusedDirectives/index.ts | 31 +++++++++++++------
3 files changed, 45 insertions(+), 12 deletions(-)
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap
index 14b8183e76de..46285b8894e1 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap
@@ -77,10 +77,10 @@ exports[`directives remark plugin - server compiler default behavior for text di
"Simple: textDirective1
Simple: textDirectiveCode
-Simple
+Simple:textDirective2
Simple
label
Simple
-Simple
+Simple:textDirective5
Simple:textDirectiveCode
"
`;
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts
index 32ab6866afe3..77910e1e442c 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts
@@ -87,3 +87,25 @@ describe('directives remark plugin - server compiler', () => {
expect(consoleMock).toHaveBeenCalledTimes(0);
});
});
+
+describe('directives remark plugin - client result === server result', () => {
+ // It is important that client/server outputs are exactly the same
+ // otherwise React hydration mismatches can occur
+ async function testSameResult(name: string) {
+ const resultClient = await processFixture(name, {compilerName: 'client'});
+ const resultServer = await processFixture(name, {compilerName: 'server'});
+ expect(resultClient).toEqual(resultServer);
+ }
+
+ it('for containerDirectives', async () => {
+ await testSameResult('containerDirectives');
+ });
+
+ it('for leafDirectives', async () => {
+ await testSameResult('leafDirectives');
+ });
+
+ it('for textDirectives', async () => {
+ await testSameResult('textDirectives');
+ });
+});
diff --git a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
index 480714df88df..99d0a1dfa6e7 100644
--- a/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
+++ b/packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
@@ -83,6 +83,22 @@ ${warningMessages}
Your content might render in an unexpected way. Visit ${customSupportUrl} to find out why and how to fix it.`;
}
+function logUnusedDirectivesWarning({
+ directives,
+ filePath,
+}: {
+ directives: Directive[];
+ filePath: string;
+}) {
+ if (directives.length > 0) {
+ const message = formatUnusedDirectivesMessage({
+ directives,
+ filePath,
+ });
+ logger.warn(message);
+ }
+}
+
function isTextDirective(directive: Directive): directive is TextDirective {
return directive.type === 'textDirective';
}
@@ -117,13 +133,6 @@ function isUnusedDirective(directive: Directive) {
const plugin: Plugin = function plugin(this: Processor): Transformer {
return (tree, file) => {
- // We only enable these warnings for the client compiler
- // This avoids emitting duplicate warnings in prod mode
- // Note: the client compiler is used in both dev/prod modes
- if (file.data.compilerName !== 'client') {
- return;
- }
-
const unusedDirectives: Directive[] = [];
visit(tree, directiveTypes, (directive: Directive) => {
@@ -138,12 +147,14 @@ const plugin: Plugin = function plugin(this: Processor): Transformer {
}
});
- if (unusedDirectives.length > 0) {
- const message = formatUnusedDirectivesMessage({
+ // We only enable these warnings for the client compiler
+ // This avoids emitting duplicate warnings in prod mode
+ // Note: the client compiler is used in both dev/prod modes
+ if (file.data.compilerName === 'client') {
+ logUnusedDirectivesWarning({
directives: unusedDirectives,
filePath: file.path,
});
- logger.warn(message);
}
};
};
From a85f049bf9da9f4a3485b7b797ccf1637fc57656 Mon Sep 17 00:00:00 2001
From: sebastienlorber
Date: Tue, 24 Oct 2023 12:20:01 +0200
Subject: [PATCH 23/24] increase playwright timeout
---
argos/playwright.config.ts | 2 ++
1 file changed, 2 insertions(+)
diff --git a/argos/playwright.config.ts b/argos/playwright.config.ts
index 31409769110c..519227c75121 100644
--- a/argos/playwright.config.ts
+++ b/argos/playwright.config.ts
@@ -14,6 +14,8 @@ import type {PlaywrightTestConfig} from '@playwright/test';
const config: PlaywrightTestConfig = {
testDir: './tests',
+ timeout: 60000,
+
reporter: [['list'], ['@argos-ci/playwright/reporter']],
// Run website production built
From 65406ac102c92a9ba2438463b5f2be85c62653ec Mon Sep 17 00:00:00 2001
From: sebastienlorber
Date: Tue, 24 Oct 2023 13:06:09 +0200
Subject: [PATCH 24/24] ignore playwright path
---
argos/tests/screenshot.spec.ts | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/argos/tests/screenshot.spec.ts b/argos/tests/screenshot.spec.ts
index 70bee2af15c3..f6829a13a9d2 100644
--- a/argos/tests/screenshot.spec.ts
+++ b/argos/tests/screenshot.spec.ts
@@ -36,8 +36,12 @@ function isBlacklisted(pathname: string) {
}
// Some paths explicitly blacklisted
const BlacklistedPathnames: string[] = [
- '/feature-requests', // Flaky because of Canny widget
- '/community/canary', // Flaky because of dynamic canary version fetched from npm
+ // Flaky because of Canny widget
+ '/feature-requests',
+ // Flaky because of dynamic canary version fetched from npm
+ '/community/canary',
+ // Long blog post with many image carousels, often timeouts
+ '/blog/2022/08/01/announcing-docusaurus-2.0',
];
return (