-
-
Notifications
You must be signed in to change notification settings - Fork 8.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(mdx-loader): Remark plugin to report unused MDX / Markdown directives #9394
Merged
Merged
Changes from 5 commits
Commits
Show all changes
27 commits
Select commit
Hold shift + click to select a range
1c2b05b
wip: unused directives plugin
OzakIOne 2f6cddb
wip: parse tree from root
OzakIOne 0478dd8
wip: unit test mock
OzakIOne f934f84
wip: better error log
OzakIOne ea124d3
Merge branch 'main' into ozaki/mdx-unused-directives
slorber cefc3e4
prevent duplicate logging of unused directives in prod build
slorber f87a0b4
fix TS vfile datamap issue
slorber 3ea1c74
wip: add text & leaf tests
OzakIOne 6a0337a
fix: include lines in path
OzakIOne e4e7255
remark unused directive tests should handle compilerName option
slorber 1b59e60
wip: improve log messages
OzakIOne b21537e
Merge branch 'main' into ozaki/mdx-unused-directives
slorber 59cb00f
update unused directives snapshots
slorber 61b41ae
refactor unused directives
slorber cb54192
refactor unused directives
slorber 10d4057
refactor unused directives
slorber b777c29
remove annoying eslint rule
slorber a142e60
change format of warning
slorber 23f6cb9
refactor
slorber 55a0abe
Implement unused simple text directive re-serialization
slorber 5fb34ae
use transformNode everywhere
slorber 764e9ab
eslint
slorber bfa8a90
eslint
slorber 99f83b2
fix bug + add client/server output mismatch tests
slorber a85f049
increase playwright timeout
slorber d7cf972
Merge branch 'main' into ozaki/mdx-unused-directives
slorber 65406ac
ignore playwright path
slorber File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
...oader/src/remark/unusedDirectives/__tests__/__fixtures__/containerDirectives.md
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
5 changes: 5 additions & 0 deletions
5
...mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/leafDirectives.md
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
11 changes: 11 additions & 0 deletions
11
...mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/textDirectives.md
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
18 changes: 18 additions & 0 deletions
18
...usaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__snapshots__/index.test.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`directives remark plugin default behavior for custom keyword 1`] = ` | ||
"<admonition type="danger"><p>Take care of snowstorms...</p></admonition> | ||
<div><p>unused directive content</p></div> | ||
<p>:::NotAContainerDirective with a phrase after</p> | ||
<p>:::</p> | ||
<p>Phrase before :::NotAContainerDirective</p> | ||
<p>:::</p>" | ||
`; | ||
|
||
exports[`directives remark plugin default behavior for custom keyword 2`] = ` | ||
[ | ||
[ | ||
"[WARNING] We found a potential error in your documentation unusedDirective "packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/__fixtures__/containerDirectives.md":7:1", | ||
], | ||
] | ||
`; |
45 changes: 45 additions & 0 deletions
45
packages/docusaurus-mdx-loader/src/remark/unusedDirectives/__tests__/index.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/** | ||
* 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 plugin from '../index'; | ||
import admonition from '../../admonitions'; | ||
|
||
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 result = await remark() | ||
.use(directives) | ||
.use(admonition) | ||
.use(plugin) | ||
.use(remark2rehype) | ||
.use(stringify) | ||
.process(file); | ||
|
||
return result.value; | ||
}; | ||
|
||
describe('directives remark plugin', () => { | ||
it('default behavior for custom keyword', async () => { | ||
const consoleMock = jest | ||
.spyOn(console, 'warn') | ||
.mockImplementation(() => {}); | ||
|
||
const result = await processFixture('containerDirectives'); | ||
|
||
expect(result).toMatchSnapshot(); | ||
|
||
expect(consoleMock.mock.calls).toMatchSnapshot(); | ||
}); | ||
}); |
72 changes: 72 additions & 0 deletions
72
packages/docusaurus-mdx-loader/src/remark/unusedDirectives/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
/** | ||
* 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 process from 'process'; | ||
import visit from 'unist-util-visit'; | ||
import logger from '@docusaurus/logger'; | ||
import {posixPath} from '@docusaurus/utils'; | ||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721 | ||
import type {Transformer, Processor, Parent} from 'unified'; | ||
import type { | ||
Directive, | ||
// @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 directiveTypes = ['containerDirective', 'leafDirective', 'textDirective']; | ||
|
||
const plugin: Plugin = function plugin(this: Processor): Transformer { | ||
return (tree, file) => { | ||
const unusedDirectives: Array<{ | ||
name: string; | ||
type: string; | ||
position: | ||
| { | ||
line: number; | ||
column: number; | ||
} | ||
| undefined; | ||
}> = []; | ||
|
||
visit<Parent>(tree, directiveTypes, (node: Directive) => { | ||
if (!node.data) { | ||
unusedDirectives.push({ | ||
name: node.name, | ||
type: node.type, | ||
position: node.position | ||
? { | ||
line: node.position.start.line, | ||
column: node.position.start.column, | ||
} | ||
: undefined, | ||
}); | ||
} | ||
}); | ||
|
||
if (unusedDirectives.length > 0) { | ||
const warningMessage = unusedDirectives | ||
.map((unusedDirective) => { | ||
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}`; | ||
}) | ||
.join('\n'); | ||
logger.warn(warningMessage); | ||
} | ||
}; | ||
}; | ||
|
||
export default plugin; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note, I'm not sure if IDEs can provide navigation if the line numbers are surrounded by ANSI sequences.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now we agreed navigation was not a goal because we need to use relative paths anyway otherwise CI tests would fail due to different absolute paths in snapshots.
And navigation apparently doesn't work in VSCode with relative paths.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tested on VSCode and in fact there is no problem opening the file from terminal even if the path is relative or surrounded by ANSI sequences (colors in the terminal am I right?)
VSCode seems to support multiple path syntax, full path, relative with or without
./
(e.g.:./website/README.md
orwebsite/README.md
)I've tested on WebStorm but it doesn't seem to have this feature (
ctrl+click
) to open file in editor (not a WebStorm user so I didn't dig too much)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, VS Code supports opening files with paths relative to the current project. I think it even supports arbitrary paths, as long as the name is unambiguous (otherwise it shows a dropdown chooser). For example
foo.tsx
can open tosrc/components/foo.tsx
.