wooorm / xdm

Just a *really* good MDX compiler. No runtime. With esbuild, Rollup, and webpack plugins
http://wooorm.com/xdm/
MIT License
595 stars 18 forks source link

Code blocks inside components are processed incorrectly. #89

Closed CyriacBr closed 3 years ago

CyriacBr commented 3 years ago

Initial checklist

Affected packages and versions: xdm@3.0

Steps to reproduce

MDX content:

<MyComp>
```js
import { Cyriac } from 'foo';
const Bar = () => <span>Hey</span>;
return Cyriac(Bar);


Résulting XDM output:
```jsx
import React from "react";
/*@jsxRuntime automatic @jsxImportSource react*/
function MDXContent(props = {}) {
  const _components = Object.assign({
    pre: "pre",
    code: "code"
  }, props.components), {ComponentWrapper, MyComp, wrapper: MDXLayout} = _components;
  const _content = <>
  <ComponentWrapper>
    <MyComp>
      <_components.pre>
        <_components.code className="language-js">
          {"import { Test } from 'foo';\nconst Bar = () => <span>Hey</span>;\nreturn Test(Bar);\n'}</_components.code></_components.pre></MyComp></ComponentWrapper></>;
  // ===================================================================>should be double quote ^
  return MDXLayout ? <MDXLayout {...props}>{_content}</MDXLayout> : _content;
}
export default MDXContent;

As you can see, the content of the codeblock is converted to a string, but the starting quote doesn't match the ending.

Link to code example: TODO

Expected behavior

import React from "react";
/*@jsxRuntime automatic @jsxImportSource react*/
function MDXContent(props = {}) {
  const _components = Object.assign({
    pre: "pre",
    code: "code"
  }, props.components), {ComponentWrapper, MyComp, wrapper: MDXLayout} = _components;
  const _content = <>
  <ComponentWrapper>
    <MyComp>
      <_components.pre>
        <_components.code className="language-js">
          {"import { Test } from 'foo';\nconst Bar = () => <span>Hey</span>;\nreturn Test(Bar);\n"}</_components.code></_components.pre></MyComp></ComponentWrapper></>;
  return MDXLayout ? <MDXLayout {...props}>{_content}</MDXLayout> : _content;
}
export default MDXContent;
wooorm commented 3 years ago

I can’t reproduce your problem. I’m getting the expected quote:

example.mdx:

<MyComp>
```js
import { Cyriac } from 'foo';
const Bar = () => <span>Hey</span>;
return Cyriac(Bar);


`example.js`:

```js
import {promises as fs} from 'node:fs'
import {compile} from './index.js'

main()

async function main() {
  const compiled = await compile(await fs.readFile('example.mdx'), {jsx: true})
  console.log(String(compiled))
}

Yields:

/*@jsxRuntime automatic @jsxImportSource react*/
function MDXContent(props = {}) {
  const _components = Object.assign({
    pre: "pre",
    code: "code"
  }, props.components), {MyComp, wrapper: MDXLayout} = _components;
  const _content = <><MyComp><_components.pre><_components.code className="language-js">{"import { Cyriac } from 'foo';\nconst Bar = () => <span>Hey</span>;\nreturn Cyriac(Bar);\n"}</_components.code></_components.pre></MyComp></>;
  return MDXLayout ? <MDXLayout {...props}>{_content}</MDXLayout> : _content;
}
export default MDXContent;
wooorm commented 3 years ago

Your output is also different in other ways from what I get compiling the given input. What options are you passing and how are you using xdm?

CyriacBr commented 3 years ago

Honestly not sure what was going anymore, I made several changes. But what's almost sure is that this isn't a XDM issue per se. Sorry to bother, will try to replicate the way you did next time.