[MDX] Support recmaPlugins
config (#5146)
* feat: support recma plugins * chore: add `test:match` to MDX * chore: changeset * docs: add recmaPlugins to README
This commit is contained in:
parent
61f7e16491
commit
308e565ad3
6 changed files with 61 additions and 2 deletions
5
.changeset/clever-keys-hammer.md
Normal file
5
.changeset/clever-keys-hammer.md
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@astrojs/mdx': patch
|
||||
---
|
||||
|
||||
Support recmaPlugins config option
|
|
@ -509,6 +509,12 @@ export default {
|
|||
}
|
||||
```
|
||||
|
||||
### recmaPlugins
|
||||
|
||||
These are plugins that modify the output [estree](https://github.com/estree/estree) directly. This is useful for modifying or injecting JavaScript variables in your MDX files.
|
||||
|
||||
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.
|
||||
|
||||
## Examples
|
||||
|
||||
- The [Astro MDX example](https://github.com/withastro/astro/tree/latest/examples/with-mdx) shows how to use MDX files in your Astro project.
|
||||
|
|
|
@ -26,7 +26,8 @@
|
|||
"build": "astro-scripts build \"src/**/*.ts\" && tsc",
|
||||
"build:ci": "astro-scripts build \"src/**/*.ts\"",
|
||||
"dev": "astro-scripts dev \"src/**/*.ts\"",
|
||||
"test": "mocha --exit --timeout 20000"
|
||||
"test": "mocha --exit --timeout 20000",
|
||||
"test:match": "mocha --timeout 20000 -g"
|
||||
},
|
||||
"dependencies": {
|
||||
"@astrojs/prism": "^1.0.1",
|
||||
|
|
|
@ -24,6 +24,7 @@ const COMPILED_CONTENT_ERROR =
|
|||
export type MdxOptions = {
|
||||
remarkPlugins?: PluggableList;
|
||||
rehypePlugins?: PluggableList;
|
||||
recmaPlugins?: PluggableList;
|
||||
/**
|
||||
* Choose which remark and rehype plugins to inherit, if any.
|
||||
*
|
||||
|
@ -64,6 +65,7 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration {
|
|||
const mdxPluginOpts: MdxRollupPluginOptions = {
|
||||
remarkPlugins: await getRemarkPlugins(mdxOptions, config),
|
||||
rehypePlugins: getRehypePlugins(mdxOptions, config),
|
||||
recmaPlugins: mdxOptions.recmaPlugins,
|
||||
jsx: true,
|
||||
jsxImportSource: 'astro',
|
||||
// Note: disable `.md` support
|
||||
|
@ -100,7 +102,10 @@ export default function mdx(mdxOptions: MdxOptions = {}): AstroIntegration {
|
|||
...(mdxPluginOpts.rehypePlugins ?? []),
|
||||
() => rehypeApplyFrontmatterExport(frontmatter),
|
||||
],
|
||||
recmaPlugins: [() => recmaInjectImportMetaEnvPlugin({ importMetaEnv })],
|
||||
recmaPlugins: [
|
||||
...(mdxPluginOpts.recmaPlugins ?? []),
|
||||
() => recmaInjectImportMetaEnvPlugin({ importMetaEnv }),
|
||||
],
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
export let recmaPluginWorking = false
|
||||
|
||||
# TOC test
|
||||
|
||||
## Table of contents
|
||||
|
@ -17,3 +19,5 @@ Oh cool, more text!
|
|||
## Section 2
|
||||
|
||||
And section 2, with a hyperlink to check GFM is preserved: https://handle-me-gfm.com
|
||||
|
||||
<div data-recma-plugin-works={recmaPluginWorking}></div>
|
||||
|
|
|
@ -4,6 +4,7 @@ import { expect } from 'chai';
|
|||
import { parseHTML } from 'linkedom';
|
||||
import { loadFixture } from '../../../astro/test/test-utils.js';
|
||||
import remarkToc from 'remark-toc';
|
||||
import { visit as estreeVisit } from 'estree-util-visit';
|
||||
|
||||
const FIXTURE_ROOT = new URL('./fixtures/mdx-plugins/', import.meta.url);
|
||||
const FILE = '/with-plugins/index.html';
|
||||
|
@ -164,6 +165,21 @@ describe('MDX plugins', () => {
|
|||
expect(selectGfmLink(document)).to.be.null;
|
||||
expect(selectRemarkExample(document)).to.be.null;
|
||||
});
|
||||
|
||||
it('supports custom recma plugins', async () => {
|
||||
const fixture = await buildFixture({
|
||||
integrations: [
|
||||
mdx({
|
||||
recmaPlugins: [recmaExamplePlugin],
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const html = await fixture.readFile(FILE);
|
||||
const { document } = parseHTML(html);
|
||||
|
||||
expect(selectRecmaExample(document)).to.not.be.null;
|
||||
});
|
||||
});
|
||||
|
||||
async function buildFixture(config) {
|
||||
|
@ -194,6 +210,24 @@ function rehypeExamplePlugin() {
|
|||
};
|
||||
}
|
||||
|
||||
function recmaExamplePlugin() {
|
||||
return (tree) => {
|
||||
estreeVisit(tree, (node) => {
|
||||
if (
|
||||
node.type === 'VariableDeclarator' &&
|
||||
node.id.name === 'recmaPluginWorking' &&
|
||||
node.init?.type === 'Literal'
|
||||
) {
|
||||
node.init = {
|
||||
...(node.init ?? {}),
|
||||
value: true,
|
||||
raw: 'true',
|
||||
};
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function selectTocLink(document) {
|
||||
return document.querySelector('ul a[href="#section-1"]');
|
||||
}
|
||||
|
@ -209,3 +243,7 @@ function selectRemarkExample(document) {
|
|||
function selectRehypeExample(document) {
|
||||
return document.querySelector('div[data-rehype-plugin-works]');
|
||||
}
|
||||
|
||||
function selectRecmaExample(document) {
|
||||
return document.querySelector('div[data-recma-plugin-works]');
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue