Skip to content

[gatsby-plugin-mdx] import names across MDX content collide #17119

@ChristopherBiscardi

Description

@ChristopherBiscardi

Description

When using MDX content from nodes, the imports have the potential to collide.

Steps to reproduce

Two MDX nodes, both used to do whatever but filtered through the node system via some source (doesn't matter which source, just have to get Mdx nodes to exist). The content of both nodes must have an import whose name conflicts with the other. This can easily be achieved with default exports since they can be re-named whenever.

import Thing from 'some/module'
import Thing from 'other-place'

Expected result

Each node, when rendered gets the appropriately named component.

Actual result

Only one of the components "survives", both renderings get the same one of the two Things.

Notes

This rarely happens in practice because of the way most of the ecosystem works. It will, however, increasingly happen as more and more people use MDX because we'll start hitting edge cases that few people use.

Path forward

We basically want to associate some Mdx content with a set of imports in gatsby-plugin-mdx. We could do this by forcing the mandatory usage of id in MDXRenderer.

<MDXRenderer mdxId={node.id}>{node.body}</MDXRenderer>

I want to find a "more automatic" way of doing this. Maybe through something that I've talked about a few times that is the ability to return components from the GraphQL API such that:

{
  mdx {
    Component
  }
}

could be used directly as

<div>
  <data.mdx.Component/>
</div>

Where the Component return is really a bootstrapped MDXRenderer with the content and the id, etc. AS a side note, this would also solve an issue with GraphQL interfaces sourced from multiple locations with different primary content types (like a BlogPost with html strings and Mdx.body strings, because the usage would be to render both with Component).

Workarounds

Typically the problem arises when the culture of an eng org is such that exports are named and destructured similarly, such as

import { Button } from 'button-red'
import { Button } from 'button-blue'

Because this is typically a cultural thing, asking the team to change habits for export naming, etc is a non-starter. The imports can be imported as such inside Mdx files instead:

import * as buttonRed from 'button-red';
import * as buttonBlue from 'button-blue';

<buttonRed.Button>Click me!</buttonRed.Button>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions