Skip to content

Commit 6e79694

Browse files
authored
refactor(docs): Add md/mdx linting via eslint and fix violations (#23168)
Adds Markdown / MDX documentation linting via the following plugins: - [eslint-mdx](https://github.com/mdx-js/eslint-mdx) - [@docusaurus/eslint-plugin](https://docusaurus.io/docs/api/misc/@docusaurus/eslint-plugin) Also fixes violations in our docs. [AB#21860](https://dev.azure.com/fluidframework/235294da-091d-4c29-84fc-cdfc3d90890b/_workitems/edit/21860)
1 parent d94bd42 commit 6e79694

14 files changed

+647
-75
lines changed

.prettierignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ packages/framework/data-object-base/es5
8080
# Generated by policy-check
8181
packages/runtime/test-runtime-utils/src/assertionShortCodesMap.ts
8282

83-
# TODO: Investigate formatting options that support JSX syntax in .mdx files
83+
# Prettier does not yet support mdx v3.
84+
# See <https://github.com/prettier/prettier/issues/12209>
8485
docs/**/*.mdx
8586

8687
# Generated

docs/.eslintignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
build
2+
node_modules
3+
docs/api
4+
versioned_docs/*/api

docs/.eslintrc.cjs

Lines changed: 79 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,73 +4,96 @@
44
*/
55

66
module.exports = {
7-
extends: [require.resolve("@fluidframework/eslint-config-fluid"), "prettier"],
87
parserOptions: {
9-
project: ["./tsconfig.json"],
8+
ecmaVersion: "2022",
109
},
11-
settings: {
12-
react: {
13-
version: "detect",
14-
},
15-
},
16-
rules: {
17-
// Required by Docusaurus for certain component exports.
18-
"import/no-default-export": "off",
19-
20-
"import/no-unassigned-import": [
21-
"error",
22-
{
23-
// Allow unassigned imports of css files.
24-
allow: ["**/*.css"],
10+
overrides: [
11+
// Rules for code
12+
{
13+
files: ["src/**/*.{ts,tsx}", "test/**/*.{ts,tsx}"],
14+
extends: [require.resolve("@fluidframework/eslint-config-fluid"), "prettier"],
15+
parserOptions: {
16+
project: ["./tsconfig.json"],
2517
},
26-
],
27-
28-
"import/no-internal-modules": [
29-
"error",
30-
{
31-
allow: ["@docusaurus/**", "@site/**", "@theme/**"],
18+
settings: {
19+
react: {
20+
version: "detect",
21+
},
3222
},
33-
],
23+
rules: {
24+
// Required by Docusaurus for certain component exports.
25+
"import/no-default-export": "off",
3426

35-
"import/no-unresolved": [
36-
"error",
37-
{
38-
ignore: ["^@docusaurus/", "^@theme/", "^@theme-original/"],
39-
},
40-
],
27+
"import/no-unassigned-import": [
28+
"error",
29+
{
30+
// Allow unassigned imports of css files.
31+
allow: ["**/*.css"],
32+
},
33+
],
4134

42-
// All dependencies in this package are dev
43-
"import/no-extraneous-dependencies": [
44-
"error",
45-
{
46-
devDependencies: true,
47-
},
48-
],
35+
"import/no-internal-modules": [
36+
"error",
37+
{
38+
allow: ["@docusaurus/**", "@site/**", "@theme/**"],
39+
},
40+
],
4941

50-
// Unfortunately, some of the import aliases supported by Docusaurus are not recognized by TSC / the eslint parser.
51-
// So we have to disable some rules that enforce strong typing.
52-
// Could be worth investigating if there's a way to make TSC aware of how the aliases are resolved, but until then,
53-
// these rules are disabled.
54-
"@typescript-eslint/no-unsafe-argument": "off",
55-
"@typescript-eslint/no-unsafe-assignment": "off",
56-
"@typescript-eslint/no-unsafe-call": "off",
57-
"@typescript-eslint/no-unsafe-member-access": "off",
58-
},
59-
overrides: [
60-
{
61-
// Test files
62-
files: ["test/**/*"],
63-
parserOptions: {
64-
project: ["./test/tsconfig.json"],
42+
"import/no-unresolved": [
43+
"error",
44+
{
45+
ignore: ["^@docusaurus/", "^@theme/", "^@theme-original/"],
46+
},
47+
],
48+
49+
// All dependencies in this package are dev
50+
"import/no-extraneous-dependencies": [
51+
"error",
52+
{
53+
devDependencies: true,
54+
},
55+
],
56+
57+
// Unfortunately, some of the import aliases supported by Docusaurus are not recognized by TSC / the eslint parser.
58+
// So we have to disable some rules that enforce strong typing.
59+
// Could be worth investigating if there's a way to make TSC aware of how the aliases are resolved, but until then,
60+
// these rules are disabled.
61+
"@typescript-eslint/no-unsafe-argument": "off",
62+
"@typescript-eslint/no-unsafe-assignment": "off",
63+
"@typescript-eslint/no-unsafe-call": "off",
64+
"@typescript-eslint/no-unsafe-member-access": "off",
6565
},
66+
overrides: [
67+
{
68+
// Test file rule overrides
69+
files: ["test/**/*"],
70+
parserOptions: {
71+
project: ["./test/tsconfig.json"],
72+
},
73+
},
74+
{
75+
// Config file tool overrides
76+
files: ["docusaurus.config.ts", "playwright.config.ts", "infra/**/*"],
77+
rules: {
78+
"import/no-internal-modules": "off",
79+
},
80+
},
81+
],
6682
},
83+
84+
// Rules for .md/.mdx documents
6785
{
68-
// Config files
69-
files: ["docusaurus.config.ts", "playwright.config.ts", "infra/**/*"],
86+
files: ["**/*.md", "**/*.mdx"],
87+
// TODO: extend prettier plugin, once prettier supports MDX v3.
88+
// See <https://github.com/prettier/prettier/issues/12209>
89+
extends: ["plugin:mdx/recommended"],
90+
plugins: ["@docusaurus/eslint-plugin"],
7091
rules: {
71-
"import/no-internal-modules": "off",
72-
"import/no-nodejs-modules": "off",
73-
"unicorn/no-process-exit": "off",
92+
// See <https://docusaurus.io/docs/api/misc/@docusaurus/eslint-plugin/no-html-links>
93+
"@docusaurus/no-html-links": "error",
94+
95+
// See <https://docusaurus.io/docs/api/misc/@docusaurus/eslint-plugin/prefer-docusaurus-heading>
96+
"@docusaurus/prefer-docusaurus-heading": "error",
7497
},
7598
},
7699
],

docs/README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,25 @@ The replacement syntax to use in `.mdx` files would be:
137137

138138
(just like you would do in a JSX context!)
139139

140+
#### Custom Heading IDs
141+
142+
In GitHub-flavored Markdown, you can assign a custom anchor ID to a heading by appending `{#<id>}` to the heading text.
143+
E.g.,
144+
145+
```markdown
146+
# Foo {#bar}
147+
```
148+
149+
Because curly braces are interpreted specially by JSX, this syntax doesn't work as is in `.mdx` documents.
150+
Instead, you'll need to escape the opening brace to prevent MDX from attempting to process the syntax as JSX.
151+
E.g.,
152+
153+
```markdown
154+
# Foo \{#bar}
155+
```
156+
157+
See the following Docusaurus issue for more context: <https://github.com/facebook/docusaurus/issues/9155>.
158+
140159
### Mermaid
141160

142161
Docusaurus has built-in support for [mermaid](https://mermaid.js.org/) diagrams.
@@ -182,7 +201,6 @@ The following npm scripts are supported in this directory:
182201
| Script | Description |
183202
|--------|-------------|
184203
| `build` | Build everything: the API documentation, the website, the tests, etc. |
185-
| `prebuild:api-documentation` | Temporary workaround for AB#24394. Cleans up existing generated API documentation before generating new content. |
186204
| `build:api-documentation` | Download API model artifacts and generate API documentation. |
187205
| `prebuild:docusaurus` | Runs pre-site build metadata generation. |
188206
| `build:docusaurus` | Build the website with Docusaurus. |

docs/docs/build/releases-and-apitags.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ There are no guarantees for API breakages or Fluid document compatibility among
3232
These are done on demand to preview new APIs or try fixes for our partners. They are represented by the `dev` tag in npm
3333
There are no guarantees for API breakages or Fluid document compatibility among the release changes. Assume you will have to throw away containers generated by older release candidates
3434

35-
## API Support Levels {#api-support-levels}
35+
## API Support Levels \{#api-support-levels}
3636

3737
For packages that are part of the `@fluidframework` scope and the `fluid-framework` package, we use import paths to communicate the stability and guarantees associated with those APIs.
3838

docs/docs/glossary.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ A Fluid container can be _attached_ or _detached_. A detached container is not c
3434
be loaded by other clients. Newly created containers begin in a detached state, which allows developers to add initial
3535
data if needed before attaching the container. Also see [Attached](#attached).
3636

37-
## Distributed data structures (DDSes) {#distributed-data-structures}
37+
## Distributed data structures (DDSes) \{#distributed-data-structures}
3838

3939
DDSes are the data structures Fluid Framework provides for storing collaborative data. As collaborators modify the data,
4040
the changes will be reflected to all other collaborators.

docs/docs/testing/telemetry.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ your other telemetry, and route the event data in whatever way you need.
1414
The `ITelemetryBaseLogger` is an interface within the `@fluidframework/common-definitions` package. This interface can
1515
be implemented and passed into the service client's constructor via the `props` parameter.
1616

17-
All Fluid service clients (for example, [AzureClient][]) and [TinyliciousClient][])) allow passing a `logger?: ITelemetryBaseLogger`
17+
All Fluid service clients (for example, [AzureClient][] and [TinyliciousClient][]) allow passing a `logger?: ITelemetryBaseLogger`
1818
into the service client props. Both `createContainer()` and `getContainer()` methods will then create an instance of the `logger`.
1919

2020
`TinyliciousClientProps` interface definition takes an optional parameter `logger`.
@@ -155,7 +155,7 @@ The Fluid Framework sends events in the following categories:
155155

156156
### EventName
157157

158-
This property contains a unique name for the event. The name may be namespaced, delimitted by a colon ':'.
158+
This property contains a unique name for the event. The name may be namespaced, delimited by a colon ':'.
159159
Additionally, some event names (not the namespaces) contain underscores '\_', as a free-form subdivision of
160160
events into different related cases. Once common example is `foo_start`, `foo_end` and `foo_cancel` for
161161
performance events.
@@ -263,15 +263,15 @@ async function start(): Promise<void> {
263263
const id = await container.attach();
264264
location.hash = id;
265265
}
266+
}
266267
```
267268

268269
Now, whenever a telemetry event is encountered, the custom `send()` method gets called and will print out the entire
269270
event object.
270271

271272
<img
272273
src="https://storage.fluidframework.com/static/images/consoleLogger_telemetry_in_action.png"
273-
alt="The
274-
ConsoleLogger sends telemetry events to the browser console for display."
274+
alt="The ConsoleLogger sends telemetry events to the browser console for display."
275275
/>
276276

277277
:::warning

docs/docs/testing/typed-telemetry.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ startTelemetry(telemetryConfig);
143143

144144
You can now run the app and see the telemetry being printed on your console.
145145

146-
### Interpreting telemetry data {#telemetry_visualization}
146+
### Interpreting telemetry data \{#telemetry_visualization}
147147

148148
This section provides a set of Azure App Insights queries related to collaborative sessions within a Fluid Framework application. It is intended to be used with the telemetry generated from @fluidframework/fluid-telemetry package whose integration steps are outline above.
149149

docs/package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@
2828
"clean:test": "rimraf --glob test-results",
2929
"clean:versions-json": "rimraf --glob ./versions.json",
3030
"download-doc-models": "node ./infra/download-doc-models.mjs",
31-
"eslint": "eslint src test --format stylish",
32-
"eslint:fix": "eslint src test --format stylish --fix",
31+
"eslint": "eslint . --format stylish",
32+
"eslint:fix": "eslint . --format stylish --fix",
3333
"format": "npm run prettier:fix",
3434
"generate-api-documentation": "dotenv -- node ./infra/generate-api-documentation.mjs",
3535
"generate-versions": "dotenv -- node ./infra/generate-versions.mjs",
@@ -61,6 +61,7 @@
6161
"devDependencies": {
6262
"@azure/static-web-apps-cli": "^2.0.1",
6363
"@docusaurus/core": "^3.6.2",
64+
"@docusaurus/eslint-plugin": "^3.6.2",
6465
"@docusaurus/module-type-aliases": "^3.6.2",
6566
"@docusaurus/plugin-content-docs": "^3.6.2",
6667
"@docusaurus/preset-classic": "^3.6.2",
@@ -85,6 +86,8 @@
8586
"dotenv-cli": "^7.4.3",
8687
"eslint": "~8.55.0",
8788
"eslint-config-prettier": "~9.1.0",
89+
"eslint-mdx": "^3.1.5",
90+
"eslint-plugin-mdx": "^3.1.5",
8891
"fs-extra": "^11.2.0",
8992
"linkcheck-bin": "3.0.0-1",
9093
"lunr": "^2.3.9",

0 commit comments

Comments
 (0)