summaryrefslogtreecommitdiff
path: root/packages/integrations/mdx
diff options
context:
space:
mode:
authorGravatar Ben Holmes <hey@bholmes.dev> 2022-10-24 14:27:37 -0400
committerGravatar GitHub <noreply@github.com> 2022-10-24 14:27:37 -0400
commit308e565ad39957e3353d72ca5d3bbce1a1b45008 (patch)
treec78fb82111092e74013c2b7091ec6b0ee85fee86 /packages/integrations/mdx
parent61f7e16491e97d0e396dfe25647d945d765fbb77 (diff)
downloadastro-308e565ad39957e3353d72ca5d3bbce1a1b45008.tar.gz
astro-308e565ad39957e3353d72ca5d3bbce1a1b45008.tar.zst
astro-308e565ad39957e3353d72ca5d3bbce1a1b45008.zip
[MDX] Support `recmaPlugins` config (#5146)
* feat: support recma plugins * chore: add `test:match` to MDX * chore: changeset * docs: add recmaPlugins to README
Diffstat (limited to 'packages/integrations/mdx')
-rw-r--r--packages/integrations/mdx/README.md6
-rw-r--r--packages/integrations/mdx/package.json3
-rw-r--r--packages/integrations/mdx/src/index.ts7
-rw-r--r--packages/integrations/mdx/test/fixtures/mdx-plugins/src/pages/with-plugins.mdx4
-rw-r--r--packages/integrations/mdx/test/mdx-plugins.test.js38
5 files changed, 56 insertions, 2 deletions
diff --git a/packages/integrations/mdx/README.md b/packages/integrations/mdx/README.md
index 0f287b44b..efb5f3b19 100644
--- a/packages/integrations/mdx/README.md
+++ b/packages/integrations/mdx/README.md
@@ -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.
diff --git a/packages/integrations/mdx/package.json b/packages/integrations/mdx/package.json
index 2a16ad801..6ef66c27e 100644
--- a/packages/integrations/mdx/package.json
+++ b/packages/integrations/mdx/package.json
@@ -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",
diff --git a/packages/integrations/mdx/src/index.ts b/packages/integrations/mdx/src/index.ts
index eb769535a..f9bf44ac0 100644
--- a/packages/integrations/mdx/src/index.ts
+++ b/packages/integrations/mdx/src/index.ts
@@ -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 {
diff --git a/packages/integrations/mdx/test/fixtures/mdx-plugins/src/pages/with-plugins.mdx b/packages/integrations/mdx/test/fixtures/mdx-plugins/src/pages/with-plugins.mdx
index fe9cac3ee..fcd8ae181 100644
--- a/packages/integrations/mdx/test/fixtures/mdx-plugins/src/pages/with-plugins.mdx
+++ b/packages/integrations/mdx/test/fixtures/mdx-plugins/src/pages/with-plugins.mdx
@@ -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>
diff --git a/packages/integrations/mdx/test/mdx-plugins.test.js b/packages/integrations/mdx/test/mdx-plugins.test.js
index 4cbfaae3e..a077fde45 100644
--- a/packages/integrations/mdx/test/mdx-plugins.test.js
+++ b/packages/integrations/mdx/test/mdx-plugins.test.js
@@ -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]');
+}