Skip to content

Commit

Permalink
Ensure maximum compatibility with mdx-bundler
Browse files Browse the repository at this point in the history
mdx-bundler doesn't document usage without its client entrypoint.
This replaces the custom implementation of `getMDXComponent` with the one exported by `mdx-bundler/client`.

We're using this patch at Vercel in nextjs.org already.
  • Loading branch information
eps1lon committed May 28, 2024
1 parent 653dbf5 commit 052d822
Show file tree
Hide file tree
Showing 5 changed files with 16 additions and 28 deletions.
11 changes: 10 additions & 1 deletion packages/@contentlayer/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@
"name": "@contentlayer2/core",
"version": "0.4.3",
"type": "module",
"exports": "./dist/index.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"./client": {
"types": "./dist/client.d.ts",
"default": "./dist/client.js"
}
},
"types": "./dist/index.d.ts",
"files": [
"./dist/**/*.{js,ts,map}",
Expand Down
1 change: 1 addition & 0 deletions packages/@contentlayer/core/src/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { getMDXComponent } from 'mdx-bundler/client'
2 changes: 1 addition & 1 deletion packages/next-contentlayer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"./package.json"
],
"scripts": {
"prepack": "awk '!/^export|^import/' dist/index-cjs.js > dist/index-cjs.cjs; cp src/hooks/jsx-runtime.cjs dist/hooks/jsx-runtime.cjs"
"prepack": "awk '!/^export|^import/' dist/index-cjs.js > dist/index-cjs.cjs"
},
"dependencies": {
"@contentlayer2/core": "workspace:*",
Expand Down
3 changes: 0 additions & 3 deletions packages/next-contentlayer/src/hooks/jsx-runtime.cjs

This file was deleted.

27 changes: 4 additions & 23 deletions packages/next-contentlayer/src/hooks/useMDXComponent.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,10 @@
import type { MDXComponents } from 'mdx/types'
// eslint-disable-next-line @typescript-eslint/ban-ts-comment -- ts-expect-error would error if consumers have setup their tsconfig correctly. It's just this tsconfig that's incorrect.
// @ts-ignore - tsconfig. is not set up yet for `exports`
import { getMDXComponent } from '@contentlayer2/core/client'
// NOTE use ESM/CommonJS compat import here until resolved: https://github.com/facebook/react/issues/11503
import React from 'react'
// NOTE use ESM/CommonJS compat import here until resolved: https://github.com/facebook/react/issues/11503
import ReactDOM from 'react-dom'

// @ts-expect-error React version workaround (This CJS workaround can be removed once Contentlayer is only targeting React 18+)
import { _jsx_runtime } from './jsx-runtime.cjs'

// NOTE This cjs-import workaround above is needed since there was a "breaking change"
// on the import/export level from React v17 to v18.
// This workaround should work in Next.js since it supports both CJS and ESM at the same time.
//
// See https://github.com/contentlayerdev/contentlayer/issues/162
// import * as _jsx_runtime from 'react/jsx-runtime'

type MDXContentProps = {
[props: string]: unknown
components?: MDXComponents
}

export const getMDXComponent = (code: string, globals: Record<string, unknown> = {}): React.FC<MDXContentProps> => {
const scope = { React, ReactDOM, _jsx_runtime, ...globals }
const fn = new Function(...Object.keys(scope), code)
return fn(...Object.values(scope)).default
}
export { getMDXComponent }

export const useMDXComponent = (code: string, globals: Record<string, unknown> = {}) => {
return React.useMemo(() => getMDXComponent(code, globals), [code, globals])
Expand Down

0 comments on commit 052d822

Please sign in to comment.