在Next.js中使用mdx-bundler:能否导入包含组件导入的组件?
问题场景
我的.mdx文件代码如下:
import MyComponent from './MyComponent' This is my *mdx* file. <MyComponent />
当MyComponent是无其他依赖的简单组件时,可正常运行:
const MyComponent = () => { return <div>Hello</div> } export default MyComponent
但当MyComponent中导入了AnotherBasicComponent后,运行失败:
import AnotherBasicComponent from './AnotherBasicComponent' const MyComponent = () => { return <div> <AnotherBasicComponent /> </div> } export default MyComponent
抛出的错误信息:
SyntaxError: Unexpected token '<'
at new Function ()
at getMDXExport (/Users/anton/projects/superdoo/node_modules/.pnpm/mdx-bundler@9.2.1_esbuild@0.15.18/node_modules/mdx-bundler/dist/client.js:44:14)
at getMDXComponent (/Users/anton/projects/superdoo/node_modules/.pnpm/mdx-bundler@9.2.1_esbuild@0.15.18/node_modules/mdx-bundler/dist/client.js:24:21)
解决办法
不是不能导入依赖其他组件的文件,问题出在mdx-bundler的编译配置上——默认情况下它可能没正确处理组件内部的JSX语法,或是没递归处理导入的组件文件。
你可以通过以下两种方式解决:
方式一:配置esbuild处理JSX和组件文件
在调用bundleMDX时,添加esbuild选项,指定JSX语法的处理规则,同时让esbuild识别.js后缀的组件文件:
import { bundleMDX } from 'mdx-bundler' async function compileMdx() { const result = await bundleMDX({ source: 你的MDX内容, cwd: process.cwd(), esbuildOptions: (opts) => { // 配置React JSX的编译规则 opts.jsxFactory = 'React.createElement' opts.jsxFragmentFactory = 'React.Fragment' // 让esbuild把.js文件当作JSX处理 opts.loader = { ...opts.loader, '.js': 'jsx' } return opts }, }) return result }
方式二:修改组件文件后缀
直接把组件文件的后缀从.js改成.jsx,esbuild会自动识别并处理其中的JSX语法,无需额外配置loader。
内容的提问来源于stack exchange,提问作者antonwilhelm

