@astrojs/mdx 0.19.4 → 0.19.5
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.
- package/README.md +66 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +6 -5
- package/dist/plugins.d.ts +3 -3
- package/dist/plugins.js +5 -0
- package/dist/rehype-optimize-static.d.ts +11 -0
- package/dist/rehype-optimize-static.js +63 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -83,6 +83,7 @@ You can configure how your MDX is rendered with the following options:
|
|
|
83
83
|
- [Options inherited from Markdown config](#options-inherited-from-markdown-config)
|
|
84
84
|
- [`extendMarkdownConfig`](#extendmarkdownconfig)
|
|
85
85
|
- [`recmaPlugins`](#recmaplugins)
|
|
86
|
+
- [`optimize`](#optimize)
|
|
86
87
|
|
|
87
88
|
### Options inherited from Markdown config
|
|
88
89
|
|
|
@@ -183,6 +184,71 @@ These are plugins that modify the output [estree](https://github.com/estree/estr
|
|
|
183
184
|
|
|
184
185
|
We suggest [using AST Explorer](https://astexplorer.net/) to play with estree outputs, and trying [`estree-util-visit`](https://unifiedjs.com/explore/package/estree-util-visit/) for searching across JavaScript nodes.
|
|
185
186
|
|
|
187
|
+
### `optimize`
|
|
188
|
+
|
|
189
|
+
- **Type:** `boolean | { customComponentNames?: string[] }`
|
|
190
|
+
|
|
191
|
+
This is an optional configuration setting to optimize the MDX output for faster builds and rendering via an internal rehype plugin. This may be useful if you have many MDX files and notice slow builds. However, this option may generate some unescaped HTML, so make sure your site's interactive parts still work correctly after enabling it.
|
|
192
|
+
|
|
193
|
+
This is disabled by default. To enable MDX optimization, add the following to your MDX integration configuration:
|
|
194
|
+
|
|
195
|
+
__`astro.config.mjs`__
|
|
196
|
+
|
|
197
|
+
```js
|
|
198
|
+
import { defineConfig } from 'astro/config';
|
|
199
|
+
import mdx from '@astrojs/mdx';
|
|
200
|
+
|
|
201
|
+
export default defineConfig({
|
|
202
|
+
integrations: [
|
|
203
|
+
mdx({
|
|
204
|
+
optimize: true,
|
|
205
|
+
})
|
|
206
|
+
]
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
#### `customComponentNames`
|
|
211
|
+
|
|
212
|
+
- **Type:** `string[]`
|
|
213
|
+
|
|
214
|
+
An optional property of `optimize` to prevent the MDX optimizer from handling any [custom components passed to imported MDX content via the components prop](https://docs.astro.build/en/guides/markdown-content/#custom-components-with-imported-mdx).
|
|
215
|
+
|
|
216
|
+
You will need to exclude these components from optimization as the optimizer eagerly converts content into a static string, which will break custom components that needs to be dynamically rendered.
|
|
217
|
+
|
|
218
|
+
For example, the intended MDX output of the following is `<Heading>...</Heading>` in place of every `"<h1>...</h1>"`:
|
|
219
|
+
|
|
220
|
+
```astro
|
|
221
|
+
---
|
|
222
|
+
import { Content, components } from '../content.mdx';
|
|
223
|
+
import Heading from '../Heading.astro';
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
<Content components={{...components, h1: Heading }} />
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
To configure optimization for this using the `customComponentNames` property, specify an array of HTML element names that should be treated as custom components:
|
|
230
|
+
|
|
231
|
+
__`astro.config.mjs`__
|
|
232
|
+
|
|
233
|
+
```js
|
|
234
|
+
import { defineConfig } from 'astro/config';
|
|
235
|
+
import mdx from '@astrojs/mdx';
|
|
236
|
+
|
|
237
|
+
export default defineConfig({
|
|
238
|
+
integrations: [
|
|
239
|
+
mdx({
|
|
240
|
+
optimize: {
|
|
241
|
+
// Prevent the optimizer from handling `h1` elements
|
|
242
|
+
// These will be treated as custom components
|
|
243
|
+
customComponentNames: ['h1'],
|
|
244
|
+
},
|
|
245
|
+
})
|
|
246
|
+
]
|
|
247
|
+
});
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Note that if your MDX file [configures custom components using `export const components = { ... }`](https://docs.astro.build/en/guides/markdown-content/#assigning-custom-components-to-html-elements), then you do not need to manually configure this option. The optimizer will automatically detect them.
|
|
251
|
+
|
|
186
252
|
## Examples
|
|
187
253
|
|
|
188
254
|
* The [Astro MDX starter template](https://github.com/withastro/astro/tree/latest/examples/with-mdx) shows how to use MDX files in your Astro project.
|
package/dist/index.d.ts
CHANGED
|
@@ -2,11 +2,13 @@ import { markdownConfigDefaults } from '@astrojs/markdown-remark';
|
|
|
2
2
|
import type { PluggableList } from '@mdx-js/mdx/lib/core.js';
|
|
3
3
|
import type { AstroIntegration } from 'astro';
|
|
4
4
|
import type { Options as RemarkRehypeOptions } from 'remark-rehype';
|
|
5
|
+
import type { OptimizeOptions } from './rehype-optimize-static.js';
|
|
5
6
|
export type MdxOptions = Omit<typeof markdownConfigDefaults, 'remarkPlugins' | 'rehypePlugins'> & {
|
|
6
7
|
extendMarkdownConfig: boolean;
|
|
7
8
|
recmaPlugins: PluggableList;
|
|
8
9
|
remarkPlugins: PluggableList;
|
|
9
10
|
rehypePlugins: PluggableList;
|
|
10
11
|
remarkRehype: RemarkRehypeOptions;
|
|
12
|
+
optimize: boolean | OptimizeOptions;
|
|
11
13
|
};
|
|
12
14
|
export default function mdx(partialMdxOptions?: Partial<MdxOptions>): AstroIntegration;
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { markdownConfigDefaults } from "@astrojs/markdown-remark";
|
|
2
2
|
import { toRemarkInitializeAstroData } from "@astrojs/markdown-remark/dist/internal.js";
|
|
3
3
|
import { compile as mdxCompile } from "@mdx-js/mdx";
|
|
4
|
-
import mdxPlugin from "@mdx-js/rollup";
|
|
5
4
|
import { parse as parseESM } from "es-module-lexer";
|
|
6
5
|
import fs from "node:fs/promises";
|
|
7
6
|
import { fileURLToPath } from "node:url";
|
|
@@ -57,8 +56,8 @@ function mdx(partialMdxOptions = {}) {
|
|
|
57
56
|
vite: {
|
|
58
57
|
plugins: [
|
|
59
58
|
{
|
|
59
|
+
name: "@mdx-js/rollup",
|
|
60
60
|
enforce: "pre",
|
|
61
|
-
...mdxPlugin(mdxPluginOpts),
|
|
62
61
|
configResolved(resolved) {
|
|
63
62
|
importMetaEnv = { ...importMetaEnv, ...resolved.env };
|
|
64
63
|
},
|
|
@@ -66,7 +65,7 @@ function mdx(partialMdxOptions = {}) {
|
|
|
66
65
|
// ex. inject layouts
|
|
67
66
|
async transform(_, id) {
|
|
68
67
|
var _a;
|
|
69
|
-
if (!id.endsWith("mdx"))
|
|
68
|
+
if (!id.endsWith(".mdx"))
|
|
70
69
|
return;
|
|
71
70
|
const { fileId } = getFileInfo(id, config);
|
|
72
71
|
const code = await fs.readFile(fileId, "utf-8");
|
|
@@ -153,7 +152,8 @@ function markdownConfigToMdxOptions(markdownConfig) {
|
|
|
153
152
|
...markdownConfig,
|
|
154
153
|
remarkPlugins: ignoreStringPlugins(markdownConfig.remarkPlugins),
|
|
155
154
|
rehypePlugins: ignoreStringPlugins(markdownConfig.rehypePlugins),
|
|
156
|
-
remarkRehype: markdownConfig.remarkRehype ?? {}
|
|
155
|
+
remarkRehype: markdownConfig.remarkRehype ?? {},
|
|
156
|
+
optimize: false
|
|
157
157
|
};
|
|
158
158
|
}
|
|
159
159
|
function applyDefaultOptions({
|
|
@@ -169,7 +169,8 @@ function applyDefaultOptions({
|
|
|
169
169
|
smartypants: options.smartypants ?? defaults.smartypants,
|
|
170
170
|
remarkPlugins: options.remarkPlugins ?? defaults.remarkPlugins,
|
|
171
171
|
rehypePlugins: options.rehypePlugins ?? defaults.rehypePlugins,
|
|
172
|
-
shikiConfig: options.shikiConfig ?? defaults.shikiConfig
|
|
172
|
+
shikiConfig: options.shikiConfig ?? defaults.shikiConfig,
|
|
173
|
+
optimize: options.optimize ?? defaults.optimize
|
|
173
174
|
};
|
|
174
175
|
}
|
|
175
176
|
function escapeViteEnvReferences(code) {
|
package/dist/plugins.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PluggableList } from '@mdx-js/mdx/lib/core.js';
|
|
2
2
|
import type { AstroConfig } from 'astro';
|
|
3
3
|
import type { VFile } from 'vfile';
|
|
4
4
|
import type { MdxOptions } from './index.js';
|
|
@@ -6,5 +6,5 @@ export declare function recmaInjectImportMetaEnvPlugin({ importMetaEnv, }: {
|
|
|
6
6
|
importMetaEnv: Record<string, any>;
|
|
7
7
|
}): (tree: any) => void;
|
|
8
8
|
export declare function rehypeApplyFrontmatterExport(): (tree: any, vfile: VFile) => void;
|
|
9
|
-
export declare function getRemarkPlugins(mdxOptions: MdxOptions, config: AstroConfig): Promise<
|
|
10
|
-
export declare function getRehypePlugins(mdxOptions: MdxOptions):
|
|
9
|
+
export declare function getRemarkPlugins(mdxOptions: MdxOptions, config: AstroConfig): Promise<PluggableList>;
|
|
10
|
+
export declare function getRehypePlugins(mdxOptions: MdxOptions): PluggableList;
|
package/dist/plugins.js
CHANGED
|
@@ -10,6 +10,7 @@ import remarkGfm from "remark-gfm";
|
|
|
10
10
|
import remarkSmartypants from "remark-smartypants";
|
|
11
11
|
import { rehypeInjectHeadingsExport } from "./rehype-collect-headings.js";
|
|
12
12
|
import rehypeMetaString from "./rehype-meta-string.js";
|
|
13
|
+
import { rehypeOptimizeStatic } from "./rehype-optimize-static.js";
|
|
13
14
|
import { remarkImageToComponent } from "./remark-images-to-component.js";
|
|
14
15
|
import remarkPrism from "./remark-prism.js";
|
|
15
16
|
import remarkShiki from "./remark-shiki.js";
|
|
@@ -116,6 +117,10 @@ function getRehypePlugins(mdxOptions) {
|
|
|
116
117
|
// computed from `astro.data.frontmatter` in VFile data
|
|
117
118
|
rehypeApplyFrontmatterExport
|
|
118
119
|
];
|
|
120
|
+
if (mdxOptions.optimize) {
|
|
121
|
+
const options = mdxOptions.optimize === true ? void 0 : mdxOptions.optimize;
|
|
122
|
+
rehypePlugins.push([rehypeOptimizeStatic, options]);
|
|
123
|
+
}
|
|
119
124
|
return rehypePlugins;
|
|
120
125
|
}
|
|
121
126
|
function getImportMetaEnvVariableName(node) {
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface OptimizeOptions {
|
|
2
|
+
customComponentNames?: string[];
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* For MDX only, collapse static subtrees of the hast into `set:html`. Subtrees
|
|
6
|
+
* do not include any MDX elements.
|
|
7
|
+
*
|
|
8
|
+
* This optimization reduces the JS output as more content are represented as a
|
|
9
|
+
* string instead, which also reduces the AST size that Rollup holds in memory.
|
|
10
|
+
*/
|
|
11
|
+
export declare function rehypeOptimizeStatic(options?: OptimizeOptions): (tree: any) => void;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { visit } from "estree-util-visit";
|
|
2
|
+
import { toHtml } from "hast-util-to-html";
|
|
3
|
+
const exportConstComponentsRe = /export\s+const\s+components\s*=/;
|
|
4
|
+
function rehypeOptimizeStatic(options) {
|
|
5
|
+
return (tree) => {
|
|
6
|
+
var _a, _b, _c, _d, _e, _f;
|
|
7
|
+
const customComponentNames = new Set(options == null ? void 0 : options.customComponentNames);
|
|
8
|
+
for (const child of tree.children) {
|
|
9
|
+
if (child.type === "mdxjsEsm" && exportConstComponentsRe.test(child.value)) {
|
|
10
|
+
const objectPropertyNodes = (_d = (_c = (_b = (_a = child.data.estree.body[0]) == null ? void 0 : _a.declarations) == null ? void 0 : _b[0]) == null ? void 0 : _c.init) == null ? void 0 : _d.properties;
|
|
11
|
+
if (objectPropertyNodes) {
|
|
12
|
+
for (const objectPropertyNode of objectPropertyNodes) {
|
|
13
|
+
const componentName = ((_e = objectPropertyNode.key) == null ? void 0 : _e.name) ?? ((_f = objectPropertyNode.key) == null ? void 0 : _f.value);
|
|
14
|
+
if (componentName) {
|
|
15
|
+
customComponentNames.add(componentName);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const allPossibleElements = /* @__PURE__ */ new Set();
|
|
22
|
+
const elementStack = [];
|
|
23
|
+
visit(tree, {
|
|
24
|
+
enter(node) {
|
|
25
|
+
const isCustomComponent = node.tagName && customComponentNames.has(node.tagName);
|
|
26
|
+
if (node.type.startsWith("mdx") || isCustomComponent) {
|
|
27
|
+
for (const el of elementStack) {
|
|
28
|
+
allPossibleElements.delete(el);
|
|
29
|
+
}
|
|
30
|
+
elementStack.length = 0;
|
|
31
|
+
}
|
|
32
|
+
if (node.type === "element" || node.type === "mdxJsxFlowElement") {
|
|
33
|
+
elementStack.push(node);
|
|
34
|
+
allPossibleElements.add(node);
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
leave(node, _, __, parents) {
|
|
38
|
+
if (node.type === "element" || node.type === "mdxJsxFlowElement") {
|
|
39
|
+
elementStack.pop();
|
|
40
|
+
const parent = parents[parents.length - 1];
|
|
41
|
+
if (allPossibleElements.has(parent)) {
|
|
42
|
+
allPossibleElements.delete(node);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
for (const el of allPossibleElements) {
|
|
48
|
+
if (el.type === "mdxJsxFlowElement") {
|
|
49
|
+
el.attributes.push({
|
|
50
|
+
type: "mdxJsxAttribute",
|
|
51
|
+
name: "set:html",
|
|
52
|
+
value: toHtml(el.children)
|
|
53
|
+
});
|
|
54
|
+
} else {
|
|
55
|
+
el.properties["set:html"] = toHtml(el.children);
|
|
56
|
+
}
|
|
57
|
+
el.children = [];
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export {
|
|
62
|
+
rehypeOptimizeStatic
|
|
63
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astrojs/mdx",
|
|
3
3
|
"description": "Add support for MDX pages in your Astro site",
|
|
4
|
-
"version": "0.19.
|
|
4
|
+
"version": "0.19.5",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"author": "withastro",
|
|
@@ -30,12 +30,12 @@
|
|
|
30
30
|
"@astrojs/markdown-remark": "^2.2.1",
|
|
31
31
|
"@astrojs/prism": "^2.1.2",
|
|
32
32
|
"@mdx-js/mdx": "^2.3.0",
|
|
33
|
-
"@mdx-js/rollup": "^2.3.0",
|
|
34
33
|
"acorn": "^8.8.0",
|
|
35
34
|
"es-module-lexer": "^1.1.1",
|
|
36
35
|
"estree-util-visit": "^1.2.0",
|
|
37
36
|
"github-slugger": "^1.4.0",
|
|
38
37
|
"gray-matter": "^4.0.3",
|
|
38
|
+
"hast-util-to-html": "^8.0.4",
|
|
39
39
|
"kleur": "^4.1.4",
|
|
40
40
|
"rehype-raw": "^6.1.1",
|
|
41
41
|
"remark-frontmatter": "^4.0.1",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"remark-shiki-twoslash": "^3.1.0",
|
|
68
68
|
"remark-toc": "^8.0.1",
|
|
69
69
|
"vite": "^4.3.1",
|
|
70
|
-
"astro": "2.5.
|
|
70
|
+
"astro": "2.5.6",
|
|
71
71
|
"astro-scripts": "0.0.14"
|
|
72
72
|
},
|
|
73
73
|
"engines": {
|