A simple babel plugin to transform mdx to solid
npm install --save-dev babel-plugin-solid-mdx
yarn add -D babel-plugin-solid-mdx
pnpm add -D babel-plugin-solid-mdx
bun add -d babel-plugin-solid-mdx
import { defineConfig } from 'vite';
import solidPlugin from 'vite-plugin-solid';
import mdx from '@mdx-js/rollup';
import solidMdx from 'babel-plugin-solid-mdx';
export default defineConfig({
plugins: [
// use @mdx-js/rollup before solidPlugin
{
enforce: 'pre',
...mdx({
jsx: true,
jsxImportSource: 'solid-js',
}),
},
solidPlugin({
// configure solid to compile `.mdx` files
extensions: ['.mdx'],
babel: {
// use the plugin to transform the mdx output
plugins: [solidMdx],
},
}),
],
});
import { defineConfig } from 'vite';
import solidPlugin from 'vite-plugin-solid';
import mdx from '@mdx-js/rollup';
import solidMdx from 'babel-plugin-solid-mdx';
import remarkFrontmatter from 'remark-frontmatter';
import remarkMdxFrontmatter from 'remark-mdx-frontmatter';
export default defineConfig({
plugins: [
{
enforce: 'pre',
...mdx({
jsx: true,
jsxImportSource: 'solid-js',
remarkPlugins: [
//
remarkFrontmatter,
remarkMdxFrontmatter,
],
}),
},
solidPlugin({
extensions: ['.mdx'],
babel: {
plugins: [solidMdx],
},
}),
],
});
The transform pipeline basically goes like this.
# heading
paragraph
- list
/*@jsxRuntime automatic*/
/*@jsxImportSource solid-js*/
function _createMdxContent(props) {
const _components = {
h1: "h1",
li: "li",
p: "p",
ul: "ul",
...props.components
};
return <><_components.h1>{"heading"}</_components.h1>{"\n"}<_components.p>{"paragraph"}</_components.p>{"\n"}<_components.ul>{"\n"}<_components.li>{"list"}</_components.li>{"\n"}</_components.ul></>;
}
export default function MDXContent(props = {}) {
const {wrapper: MDXLayout} = props.components || ({});
return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);
}
solid-js
transforms jsx elements into createComponent
calls which doesn't support string tags. This plugins transforms jsx elements with potential string tags to use Dynamic
instead.
import { Dynamic } from "solid-js/web"
/*@jsxRuntime automatic*/
/*@jsxImportSource solid-js*/
function _createMdxContent(props) {
const _components = {
h1: "h1",
li: "li",
p: "p",
ul: "ul",
...props.components
};
return <><Dynamic component={_components.h1}>{"heading"}</Dynamic>{"\n"}<Dynamic component={_components.p}>{"paragraph"}</Dynamic>{"\n"}<Dynamic component={_components.ul}>{"\n"}<Dynamic component={_components.li}>{"list"}</Dynamic>{"\n"}</Dynamic></>;
}
export default function MDXContent(props = {}) {
const {wrapper: MDXLayout} = props.components || ({});
return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props} /></MDXLayout> : _createMdxContent(props);
}
And the rest is handled by solid-js
babel transform.