reactjs 从MDX字符串获取组件及其属性的列表-通过正则表达式?

siotufzp  于 2022-12-26  发布在  React
关注(0)|答案(1)|浏览(195)

我的问题-从MDX/JSX字符串获取组件和属性

我有一个MDX字符串,其中包含YAML格式的Front-matter meta data、一些常规文本、一些markdown和一些React组件。
我需要从中获取所有React(非HTML)组件及其参数的列表。
举个例子:

---
title: Title of documents
tags: one, two, three
---

# My heading H1

Some text in paragraph. Than the list:
 - First item
 - Second item

More text with [a link](https://example.com).

<Articles category="theatre" count={3} />

Further text with more information.

<Newsletter categories={['theatre', 'design']} />

<MultilineComponent 
  paramA="A"
  paramB="B"
/>

<ComponentWithChildren param="value">
  Some children
</ComponentWithChildren>

...我需要以下输出:

[
  {
    component: 'Articles',
    props: {
      category: 'theatre',
      count: 3,
    },
  },
  {
    component: 'Newsletter',
    props: {
      categories: ['theatre', 'design'],
    }
  },
  {
    component: 'MultilineComponent',
    props: {
      paramA: 'A',
      paramB: 'B',
    }
  },
  {
    component: 'ComponentWithChildren',
    props: {
      param: 'value',
    }

  }
]

我还需要在服务器上执行此操作,因此无法访问浏览器功能(窗口、文档等)。

我所尝试的

一些基本的正则表达式,但由于我远不是专业的正则表达式,now I have two problems。:)
是否有一些内置的方法来解析JSX字符串,以获得组件和 prop 的列表,就像我上面描述的那样?或者是否有一些其他的解析器可以用来解决这个问题?如果没有,是否有一些Regex模式可以用来获得这个问题?

快速总结“为什么”

在构建Next.js项目的过程中,我需要确定包中每个MDX页面实际需要哪些数据。因此,如果我在Mdx文件中看到以下内容:

...other text

<Articles category="theatre" count={3} />

...other text

......我可以解析成这样:

component: "Articles"
category: "theatre"
count: 3

这些信息足以让我知道我需要将这些数据发送到页面:

[
  {
    title: 'Romeo and Juliet',
    category: 'theatre',
  },
  {
    title: 'The Cherry Orchard',
    category: 'theatre',
  },
  {
    title: 'Death of a Salesman',
    category: 'theatre',
  }
]

你能帮我一下吗?先谢谢你!💪

5cnsuln7

5cnsuln71#

不确定用正则表达式解析JSX是否有效,因为花括号{...}可以包含任何JS表达式,所以如果选择这种方式,那么也要准备解析Javascript。
幸运的是,有很多JSX解析器可以帮你做这件事。例如,我选择的第一个解析器是jsx-parser,这个小家伙可以解析你的例子(用一个简单的技巧)。结果的形状非常不同,但是你可以转换它来满足你的需要。

var test = `
---
title: Title of documents
tags: one, two, three
---

# My heading H1

Some text in paragraph. Than the list:
 - First item
 - Second item

More text with [a link](https://example.com).

<Articles category="theatre" count={3} />

Further text with more information.

<Newsletter categories={['theatre', 'design']} />

<MultilineComponent 
  paramA="A"
  paramB="B"
/>

<ComponentWithChildren param="value">
  Some children
</ComponentWithChildren>
`

const components = [...test.matchAll(/<[A-Z]/g)]
  .map(match => JSXParser(test.slice(match.index)))

document.getElementById('result').textContent = JSON.stringify(components, null, 2)
<script src="https://unpkg.com/jsx-parser@1.0.8/index.umd.js"></script>

<pre id="result">Hello</pre>
  • 在我的代码片段中,我使用了UMD版本的包,但对于node.js,请考虑选择ES模块ofc。*

相关问题