web-infra-dev / rspress

🦀💨 A fast Rspack-based static site generator.
https://rspress.dev
MIT License
1.48k stars 139 forks source link

[Feature]: Supports internal nested use components such as txt, and supports parsing the content within the component #1362

Open bosens-China opened 3 months ago

bosens-China commented 3 months ago

这个功能解决了什么问题?

  1. 如果支持txt使用组件,可以跟md更好结合,考虑一个场景,我用组件写了三个li,但是我希望它被 sh包裹起来,但是目前的实现,就直接不会解析组件内的组件。
  2. 支持解析组件内容,如果我在组件内返回一个文本,正常在md文件中写一串文本会被p标签包裹起来,但是组件如果返回文本不回被处理,但是问题在于,默认的主题对p进行了封装。

你期望的 API 是什么样子的?

暂无

Timeless0911 commented 3 months ago

Please provide some demo codes or repo.

bosens-China commented 3 months ago

稍后,明天提供

bosens-China commented 3 months ago

1. 支持md语法内嵌套使用组件,并且组件内容被md渲染

这样做是有实际场景的,例如我有一个Text的组件,他的作用很简单,就是对于一些特定的词进行span标签包裹起来,然后重点标记。 但是我在mdx中嵌套使用这个组件不会被md重新解析。

例如,我在md写一行文本,会最终会p标签包裹起来,大概这样

<p>hello<p>

但是如果我在正文内使用 <Text>hello <Text>,最终的显示就是我Text组件内部返回的。

2. 支持 ``` 嵌套使用组件

我很喜欢press的配色,我在使用 ``` txt包裹一段文本,看起来很舒服,但是如果我在里面嵌套使用组件不回被解析,所以希望可以支持这个功能。

或者如果不支持上述功能,因为你渲染自动给p标签添加了一些class,我有什么办法,能直接用你的内置组件呢?

@Timeless0911

Timeless0911 commented 3 months ago

你说的包括你之前的 issue https://github.com/web-infra-dev/rspress/issues/1361 都在试图在 mdx 编译层面,对于 mdx 以及 mdx 插件解析的语法,试图应用 react 组件动态化的结果,这是两个阶段的事情。

比如你的源码是

import { Text } from '@/components/text';

# <Text />

```js
<Text />
export function Text() {
  return <>ss</>;
}

经过 @mdx-rs 编译后产生的应该是

import { useMDXComponents as _provideComponents } from "@mdx-js/react";
import { Text } from '@/components/text';
function _createMdxContent(props) {
    const _components = Object.assign({
        h1: "h1",
        a: "a",
        pre: "pre",
        code: "code"
    }, _provideComponents(), props.components);
    return <><_components.h1 id=""><Text/><_components.a className="header-anchor" aria-hidden="true" href="#">{"#"}</_components.a></_components.h1>{"\n"}<_components.pre><_components.code className="language-js">{"<Text />\n"}</_components.code></_components.pre></>;
}
function MDXContent(props = {}) {
    const { wrapper: MDXLayout } = Object.assign({}, _provideComponents(), props.components);
    return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout> : _createMdxContent(props);
}
export default MDXContent;

然后去应用 https://github.com/web-infra-dev/rspress/tree/main/packages/theme-default/src/layout/DocLayout/docComponents 的样式最终生成 html 文件

bosens-China commented 3 months ago

你说的包括你之前的 issue #1361 都在试图在 mdx 编译层面,对于 mdx 以及 mdx 插件解析的语法,试图应用 react 组件动态化的结果,这是两个阶段的事情。

比如你的源码是

import { Text } from '@/components/text';

# <Text />

```js
<Text />
export function Text() {
  return <>ss</>;
}

经过 @mdx-rs 编译后产生的应该是

import { useMDXComponents as _provideComponents } from "@mdx-js/react";
import { Text } from '@/components/text';
function _createMdxContent(props) {
    const _components = Object.assign({
        h1: "h1",
        a: "a",
        pre: "pre",
        code: "code"
    }, _provideComponents(), props.components);
    return <><_components.h1 id=""><Text/><_components.a className="header-anchor" aria-hidden="true" href="#">{"#"}</_components.a></_components.h1>{"\n"}<_components.pre><_components.code className="language-js">{"<Text />\n"}</_components.code></_components.pre></>;
}
function MDXContent(props = {}) {
    const { wrapper: MDXLayout } = Object.assign({}, _provideComponents(), props.components);
    return MDXLayout ? <MDXLayout {...props}><_createMdxContent {...props}/></MDXLayout> : _createMdxContent(props);
}
export default MDXContent;

然后去应用 https://github.com/web-infra-dev/rspress/tree/main/packages/theme-default/src/layout/DocLayout/docComponents 的样式最终生成 html 文件

老哥看你说的这段话我大概明白意思,不过我比较困惑的是,对于静态文档资源,react组件基本上是固定的内容,经过mdx解析之后被处理是有什么其他问题吗。

Timeless0911 commented 3 months ago

没太理解你的意思,什么叫「固定的内容」,「之后被处理」是啥意思,你觉得应该怎么做呢

bosens-China commented 3 months ago

没太理解你的意思,什么叫「固定的内容」,「之后被处理」是啥意思,你觉得应该怎么做呢

就是类似于next说的ssg,它允许你有服务器组件和客户端组件,对于服务器组件默认情况下是不可不变的,这块应该你们也是支持的。 就是我的意思是说,对于非客户端组件,它返回的内容只跟接收的props相关,而不会有useEffect这样的副作用,是可以被固定话的。

之前说的# 如果能在运行的时候直接运行组件得到一个结果值,对于变化的也无所谓直接当成客户端组件,运行时候变化也没啥。

说的可能有点不够清晰,没有深入解除过这块,只是我觉得对于我使用的tsx组件,在build的时候都可以得到一个固定化的内容,那在mdx解析阶段应该也是可以做到吧。 = =

Timeless0911 commented 3 months ago

你的需求本身我是理解的,但是你说的「在mdx解析阶段应该也是可以做到」非常难实现,你应该是把动态化的组件使用 mdx 文件去引入片段,tsx 肯定是做不到的。

bosens-China commented 3 months ago

是的,其实我在编写一个学习的文档地址,例如对于标题,如果是本课新词我想让他高亮显示。 但是现在我发现没办法实现了,只能借用你们内部的组件来完成。 但是我更期待的是你们可以提供一种方式可以满足这部分的场景🥰 @Timeless0911

Timeless0911 commented 3 months ago

PR is welcome.

bosens-China commented 3 months ago

@Timeless0911 老哥我去问了下gpt,它给了一个回答,不过我对mdx的生态不太了解,你帮忙瞅瞅可行否

image

Timeless0911 commented 3 months ago

You can try it yourself.