@bacons/mdx

中文文档
1.0.3发布于 2026/03/30MITTypeScriptCommonJS构建来源已验证近 30 天下载 5889

用于 Expo 路由器的通用 MDX 渲染器

中文使用文档
文档目录16 节
  1. 将软件包添加到您的 npm 依赖性
  2. 设置
  3. 使用量
  4. 自定义组件
  5. 自定义样式
  6. 字体
  7. 实验本地错误
  8. 只网络组件
  9. 下一个.js 用法
  10. 远程 MDX
  11. 服务器侧编译
  12. 客户端渲染
  13. 如何运作
  14. 前题
  15. 已知问题
  16. 关于这个项目

@ bacons/ mdx (英语)

通用 磁共振 用于博览会的应用程序和网站.

  • Build-time MDX以回放原生或回放DOM组件.
  • 服务器将MDX交给一个CMS下载内容.
  • 自定义组件和样式定义 .

将软件包添加到您的 npm 依赖性

bun add @bacons/mdx

设置

添加导入支持 md 财务报告和审定财务报表 mdx 在您的文件中 metro.config.js 文档.

metro.config.js

const { getDefaultConfig } = require("expo/metro-config");
const { withMdx } = require("@bacons/mdx/metro");

const config = withMdx(getDefaultConfig(__dirname));

module.exports = config;
手动设置

如果你需要自定义 babelTransformerPath 更多, 不使用此手动设置 :

metro.config.js

const { getDefaultConfig } = require("expo/metro-config");

const config = getDefaultConfig(__dirname);

config.resolver.sourceExts.push("md", "mdx");

config.transformer.babelTransformerPath = require.resolve("./transformer.js");

module.exports = config;

创建自定义地铁变压器 。 用于将MDX文件转换为JS + React Industrial后再与Babel相接.

./transformer.js

const upstreamTransformer = require("@expo/metro-config/babel-transformer");
const MdxTransformer = require("@bacons/mdx/metro-transformer");

module.exports.transform = async (props) => {
  // Then pass it to the upstream transformer.
  return upstreamTransformer.transform(
    // Transpile MDX first.
    await MdxTransformer.transform(props)
  );
};

使用量

创建下标文件 :

./demo.mdx

import { CustomComponent } from './my-custom-component';

# Hello World

I **am** a _markdown_ file!

<CustomComponent />

此文件可导入并作为反应组件处理 :

./App.js

import Demo from "./demo.mdx";

export default function App() {
  return <Demo />;
}

自定义组件

默认情况下,这个软件包对DOM元素使用一套不完整的通用回放原生组件. 您可能想要改进组件, 添加更多, 或者把它们交换给您自己 .

import { Text } from "react-native";
import { MDXComponents } from "@bacons/mdx";

export default function App() {
  return (
    <Demo
      components={{
        h1: (props) => <h1 {...props} />,
        // Add custom components which can be used as JSX elements.
        RedText: (props) => <Text {...props} style={{ color: "red" }} />,
        // This can be used as `<RedText />` without the need to import it.
      }}
    />
  );
}

现在,您可以使用自定义组件 :

# Hello World

<RedText />

您可以使用 MDXComponents 反应上下文组件 .

import { Text } from "react-native";
import { MDXComponents } from "@bacons/mdx";

export default function App() {
  // Pass any HTML element as a key to the MDXComponents component.
  return (
    <MDXComponents
      components={{
        h1: (props) => <Text {...props} />,
        // Add custom components which can be used as JSX elements.
        RedText: (props) => <Text {...props} style={{ color: "red" }} />,
        // This can be used as `<RedText />` without the need to import it.
      }}
    >
      <Demo />
    </MDXComponents>
  );
}

一定要通过 style 向下推到你使用的组件, 这就是样式的级联.

自定义样式

这个软件包与大多数文件网站类似。 你为整个网站创造了高级风格. 这可以被分级缩小一个风格的范围.

import { MDXStyles } from "@bacons/mdx";

export default function App() {
  // Pass any HTML element as a key to the MDXStyles component.
  return (
    <MDXStyles
      h1={{
        fontSize: 32,
        fontWeight: "bold",
        color: "red",
      }}
    >
      <Demo />
    </MDXStyles>
  );
}

这个 <MDXStyles> 组件可以堆放在不同级别,想想这些像CSS类.

字体

您可以为导入添加支持 .mdx 在您的文件中 tsconfig.json 文档.

tsconfig.json

{
  "compilerOptions": {
    "typeRoots": ["./global.d.ts"]
  },
  "extends": "expo/tsconfig.base"
}

现在创建一个文件来宣布模块.

./global.d.ts

declare module "*.mdx" {
  import React from "react";
  import { CustomComponentsProp } from "@bacons/mdx";
  const Component: React.FC<{
    components?: CustomComponentsProp;
  }>;
  export default Component;
}

实验本地错误

可选的本土唯一步骤,MDX不需要工作.

React Industrial在本地使用 React DOM 组件或将字符串制成外部时,其错误信息不理想 <Text /> 要素。 这会使迁徙和代码共享非常痛苦. 这个软件包有一个实验性的 dev-唯一功能,在本地化上渲染出div,p,h1等内置反应时打印出优化错误.

简而言之,在你的 babel.config.js,并清除变换缓存 npx expo start --clear数字 :

module.exports = function (api) {
  api.cache(true);
  return {
    presets: [["babel-preset-expo", { jsxImportSource: "@bacons/mdx/jsx" }]],
  };
};

当你在本地生成一个 div, p, h1 等时, 你会得到一个有用的错误信息 .

export default function App() {
  return <div>Hey</div>;
}
ERROR  Unsupported DOM <p /> at: /Users/evanbacon/Documents/GitHub/bacons/mdx/apps/demo/src/App.tsx:1:11
This will break in production.

只网络组件

可以将MDX分解为DOM元素,而不是通用组件. 这在只建网络或只从网络迁移时可能有用. 要做到这一点,拉入 getDOMComponents 函数并传递给 components mDX组件的道具.

import { getDOMComponents } from "@bacons/mdx";

import Demo from "./readme.md";

export default function App() {
  return <Demo components={getDOMComponents()} />;
}

这将使下列MDX成为DOM元素:

# Hello World

I **am** a _markdown_ file!

还有DOM:

<h1>Hello World</h1>
<p>I <strong>am</strong> a <em>markdown</em> file!</p>

下一个.js 用法

  1. 遵循此处详述的步骤: https://nextjs.org/docs/advanced-features/using-mdx 互联网档案馆的存檔,存档日期2013-12-21
  2. 将以下软件包添加到 transpile-modules 在您内部 next.config.js数字 :
    '@bacons/mdx',
    '@bacons/react-views',
    '@expo/html-elements',
    

远程 MDX

从远程服务器装入并渲染 MDX 内容 。 这对CMS驱动的内容、博客文章或任何需要运行时获取的MDX都有用.

服务器侧编译

首先,在您的服务器上编译 MDX( API 路由、 边缘功能或构建脚本) :

// app/api/mdx+api.ts (Expo Router API route)
import { compileMDX } from "@bacons/mdx/server";

export async function GET(request: Request) {
  const url = new URL(request.url);
  const slug = url.searchParams.get("slug");

  // Fetch MDX content from your CMS or file system
  const mdxSource = `
# Hello World

This is **bold** text with a <CustomButton>Click me</CustomButton>.
  `;

  const compiled = await compileMDX(mdxSource);

  return Response.json(compiled);
}

这个 compileMDX 函数接受可选的语句并重排插件 :

const compiled = await compileMDX(mdxSource, {
  remarkPlugins: [remarkGfm],
  rehypePlugins: [rehypeHighlight],
});

客户端渲染

使用 RemoteMDX 构成部分和 useMDXFetch 获取和渲染远程 MDX 的钩子 :

import { RemoteMDX, useMDXFetch, MDXComponents } from "@bacons/mdx";
import { Text, ActivityIndicator } from "react-native";

function BlogPost({ slug }: { slug: string }) {
  const { content, loading, error } = useMDXFetch(`/api/mdx?slug=${slug}`);

  if (loading) return <ActivityIndicator />;
  if (error) return <Text>Error: {error.message}</Text>;
  if (!content) return null;

  return (
    <MDXComponents
      components={{
        CustomButton: (props) => (
          <Text {...props} style={{ color: "blue" }} />
        ),
      }}
    >
      <RemoteMDX source={content} />
    </MDXComponents>
  );
}

您也可以亲自获取内容并直接传递:

import { RemoteMDX, type CompiledMDX } from "@bacons/mdx";

function BlogPost({ content }: { content: CompiledMDX }) {
  return <RemoteMDX source={content} />;
}

如何运作

  1. 服务器: 将 MDX 编译为 JSON 可执行 AST 格式( 非可执行 JavaScript)
  2. 客户端: 获取 JSON 并使用现有的组件系统使其
  3. 警卫: 无 eval() 或代码执行 - AST 是纯数据
  4. 构成部分: 自定义组件通过 MDXComponents 语境或 components 道具
  5. 样式数字 : MDXStyles 完全支持上下文

前题

前题被提取出来,并可在编译的产出中找到:

const compiled = await compileMDX(`
---
title: My Post
date: 2024-01-01
---

# Content here
`, {
  remarkPlugins: [remarkFrontmatter, remarkMdxFrontmatter],
});

console.log(compiled.frontmatter);
// { title: "My Post", date: "2024-01-01" }

访问客户端的前题 :

function BlogPost({ slug }: { slug: string }) {
  const { content } = useMDXFetch(`/api/mdx?slug=${slug}`);

  return (
    <>
      <Text>{content?.frontmatter?.title}</Text>
      <RemoteMDX source={content} />
    </>
  );
}

已知问题

  • 哦,LI, ul是所有buggy。 公关欢迎.
  • 原生图像比例很奇怪.

关于这个项目

这是一个通用的 MDX Expo (React & Metro) 执行. 它旨在成为利用通用地铁(Expo CLI)的博览会项目的通用MDX执行.

  • 测试 apps/demo 项目.

这个图书馆授权我(伊凡培根) 个人博客,这里可以找到来源 : 埃文·培根组合。 。 。 .

版本与发布记录

@bacons/mdx 共发布 28 个版本,首次发布于 2022/12/14;过去 12 个月发布了 7 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
1.0.3latest2026/03/307 个月前
1.0.22026/01/149 个月前
1.0.12026/01/149 个月前
0.5.52026/01/149 个月前
0.5.32026/01/149 个月前
0.5.22026/01/149 个月前

关于 @bacons/mdx 的常见问题

@bacons/mdx 是什么?

用于 Expo 路由器的通用 MDX 渲染器

如何安装 @bacons/mdx?

在项目目录运行 npm install @bacons/mdx,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react-native(*)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@bacons/mdx 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@bacons/mdx 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@bacons/mdx 可以商用吗?

@bacons/mdx 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@bacons/mdx 的下载量有多少?

根据 npm 官方下载统计,@bacons/mdx 在 2026/10/08 – 2026/11/06 这 30 天内被下载 5,889 次,日均约 196 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@bacons/mdx 还在维护吗?

最新版本 1.0.3 发布于 2026/03/30(7 个月前);至今共发布 28 个版本,其中过去 12 个月发布了 7 个;首次发布于 2022/12/14。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。