Skip to content

Commit

Permalink
Fix injecting providers for jsx in esm, expressions
Browse files Browse the repository at this point in the history
Closes GH-2449.
Related-to: facebook/docusaurus#9905.
  • Loading branch information
wooorm committed Mar 6, 2024
1 parent 7dc3766 commit c747990
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 5 deletions.
18 changes: 18 additions & 0 deletions packages/mdx/lib/plugin/remark-mark-and-unravel.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*/

import {collapseWhiteSpace} from 'collapse-white-space'
import {walk} from 'estree-walker'
import {visit} from 'unist-util-visit'

/**
Expand Down Expand Up @@ -92,6 +93,23 @@ export function remarkMarkAndUnravel() {
const data = node.data || (node.data = {})
data._mdxExplicitJsx = true
}

if (
(node.type === 'mdxFlowExpression' ||
node.type === 'mdxTextExpression' ||
node.type === 'mdxjsEsm') &&
node.data &&
node.data.estree
) {
walk(node.data.estree, {
enter(node) {
if (node.type === 'JSXElement') {
const data = node.data || (node.data = {})
data._mdxExplicitJsx = true
}
}
})
}
})
}
}
97 changes: 92 additions & 5 deletions packages/mdx/test/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -1246,11 +1246,7 @@ test('@mdx-js/mdx: compile (JSX)', async function (t) {
'/*@jsxRuntime automatic*/',
'/*@jsxImportSource react*/',
'function _createMdxContent(props) {',
' const _components = {',
' "a-b": "a-b",',
' ...props.components',
' }, _component0 = _components["a-b"];',
' return <>{<_component0></_component0>}</>;',
' return <>{<a-b></a-b>}</>;',
'}',
'export default function MDXContent(props = {}) {',
' const {wrapper: MDXLayout} = props.components || ({});',
Expand Down Expand Up @@ -1351,6 +1347,97 @@ test('@mdx-js/mdx: compile (JSX)', async function (t) {
}
)

await t.test(
'should not inject a provider for JSX in ESM',
async function () {
assert.equal(
String(
await compile(
'export function A() { return <span /> }\n\nexport class B { render() { return <div /> } }',
{providerImportSource: '@mdx-js/react'}
)
),
[
'import {Fragment as _Fragment, jsx as _jsx} from "react/jsx-runtime";',
'import {useMDXComponents as _provideComponents} from "@mdx-js/react";',
'export function A() {',
' return _jsx("span", {});',
'}',
'export class B {',
' render() {',
' return _jsx("div", {});',
' }',
'}',
'function _createMdxContent(props) {',
' return _jsx(_Fragment, {});',
'}',
'export default function MDXContent(props = {}) {',
' const {wrapper: MDXLayout} = {',
' ..._provideComponents(),',
' ...props.components',
' };',
' return MDXLayout ? _jsx(MDXLayout, {',
' ...props,',
' children: _jsx(_createMdxContent, {',
' ...props',
' })',
' }) : _createMdxContent(props);',
'}',
''
].join('\n')
)
}
)

await t.test(
'should not inject a provider for JSX in expressions',
async function () {
console.log(
String(
await compile('{ <span /> }\n\nAnd also { <div /> }.', {
providerImportSource: '@mdx-js/react'
})
)
)
assert.equal(
String(
await compile('{ <span /> }\n\nAnd also { <div /> }.', {
providerImportSource: '@mdx-js/react'
})
),
[
'import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";',
'import {useMDXComponents as _provideComponents} from "@mdx-js/react";',
'function _createMdxContent(props) {',
' const _components = {',
' p: "p",',
' ..._provideComponents(),',
' ...props.components',
' };',
' return _jsxs(_Fragment, {',
' children: [_jsx("span", {}), "\\n", _jsxs(_components.p, {',
' children: ["And also ", _jsx("div", {}), "."]',
' })]',
' });',
'}',
'export default function MDXContent(props = {}) {',
' const {wrapper: MDXLayout} = {',
' ..._provideComponents(),',
' ...props.components',
' };',
' return MDXLayout ? _jsx(MDXLayout, {',
' ...props,',
' children: _jsx(_createMdxContent, {',
' ...props',
' })',
' }) : _createMdxContent(props);',
'}',
''
].join('\n')
)
}
)

await t.test(
'should serialize double quotes in attribute values',
async function () {
Expand Down

0 comments on commit c747990

Please sign in to comment.