An alternative “shortcode” (`mdxType` alternative) proposal
See original GitHub issueCurrently, MDX is walking the whole JS program, and adding an mdxType
prop to all JSX elements. It does this, so components can be overwritten at runtime.
Take this MDX:
* a
* b
Which turns into (simplified to get the point across, the actual is more complex):
var ol = () => throw "error"
var li = () => throw "error"
<ol mdxType="ol">
<li mdxType="li" parentName="ol">a</li>
<li mdxType="li" parentName="ol">b</li>
</ol>
After compiling the JSX away, you get:
var ol = () => throw "error"
var li = () => throw "error"
func(ol {mdxType: "ol"}, [
func(li, {mdxType: "li", parentName: "ol"}, ["a"]),
func(li, {mdxType: "li", parentName: "ol"}, ["b"]),
])
Then, the runtime, supports replacing things through components
.
It has a func
that ignores its first argument, instead taking mdxType
(and parentName
) to look whether it has a different component defined in components
, and uses that instead of the either imported or defined throwing components.
The above is the simplified example for “normal” tags. The same happens for actual components (Capitalized):
var MyComponent = () => throw "error"
func(MyComponent, {mdxType: "MyComponent"}, [])
Which is then overwritten at runtime…
Even weirder is:
import MyComponent from "place"
func(MyComponent, {mdxType: "MyComponent"}, [])
// Passed in runtime:
{components: {"MyComponent": () => /* this is used instead of the imported component! */}}
This ✨ magic ✨ is complex and undocumented. I want to remove that complexity. Here’s one alternative.
We instead compile all standard markdown (html?) things to a namespace object: p
becomes mdx.p
, strong
becomes mdx.strong
, etc:
<mdx.ol>
<mdx.li>a</mdx.li>
<mdx.li>a</mdx.li>
</mdx.ol>
Then, in mdxContent
(the wrapper function around all JSX components), we’re being passed runtime components. We take those and use them to fill mdx.p = components.p || 'p'
.
This might solve #821, because the JSX <p>x</p>
is not overwritten whereas the markdown paragraph x
is, depending on where we implement the changing of p
to mdx.p
.
This then has no knowledge of JSX: there is no tree traversed for whether <MyComponent />
is imported or not. You have to import it, you can’t just pass it Youtube
to components
, you have to import it.
/cc @johno, @ChristianMurphy
Issue Analytics
- State:
- Created 3 years ago
- Comments:12 (12 by maintainers)
Top GitHub Comments
Yes, totally, abbreviated that just to be shorter, but it’s currently
function MDXContent({components, ...props})
and I don’t intend changing that!landed