Skip to content

Commit 325f598

Browse files
authored
feat: add bundleMDXFile to make working with on-disk content easier. (#83)
* fix: read the front matter from the esbuild entry point if the user has specified one, closes #79 * feat: add `bundleMDXFile` to make working with on-disk content easier. BREAKING CHANGE: Update to xdm@2. This version should be safe to upgrade to without any changes, but it's possible there will be done breaking changes in some transitive dependencies that could affect you.
1 parent c56b34d commit 325f598

File tree

5 files changed

+99
-24
lines changed

5 files changed

+99
-24
lines changed

README.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -593,23 +593,24 @@ const {code} = await bundleMDX(mdxSource, {
593593
})
594594
```
595595

596-
### Replacing the entry point
596+
### bundleMDXFile
597597

598598
If your MDX file is on your disk you can save some time and code by having
599-
`esbuild` read the file for you. To do this you can override the `entryPoints`
600-
settings in `esbuildOptions` with the path to your mdx source.
599+
`esbuild` read the file for you. To do this mdx-bundler provides the function
600+
`bundleMDXFile` which works the same as `bundleMDX` except it's first option is
601+
the path to the mdx file instead of the mdx source.
601602

602603
```js
603-
const {code, frontmatter} = await bundleMDX('', {
604-
cwd: '/users/you/site/_content/pages',
605-
esbuildOptions: options => {
606-
options.entryPoints = ['/users/you/site/_content/pages/file.mdx']
604+
import {bundleMDXFile} from 'mdx-bundler'
607605

608-
return options
609-
},
610-
})
606+
const {code, frontmatter} = await bundleMDXFile(
607+
'/users/you/site/content/file.mdx',
608+
)
611609
```
612610

611+
`cwd` will be automatically set to the `dirname` of the given file path, you can
612+
still override this. All other options work the same as they do for `bundleMDX`.
613+
613614
### Known Issues
614615

615616
#### Cloudflare Workers

other/sample.mdx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
title: 'Sample'
3+
---
4+
5+
import {Sample} from './sample-component'
6+
7+
This is a sample mdx file that should demo mdx-bundlers features.
8+
9+
<Sample />

package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,29 +40,29 @@
4040
"validate": "kcd-scripts validate"
4141
},
4242
"dependencies": {
43-
"@babel/runtime": "^7.14.6",
43+
"@babel/runtime": "^7.15.3",
4444
"@esbuild-plugins/node-resolve": "^0.1.4",
4545
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
4646
"gray-matter": "^4.0.3",
47-
"remark-frontmatter": "^3.0.0",
47+
"remark-frontmatter": "^4.0.0",
4848
"remark-mdx-frontmatter": "^1.0.1",
4949
"uuid": "^8.3.2",
50-
"xdm": "^1.12.2"
50+
"xdm": "^2.0.0"
5151
},
5252
"peerDependencies": {
5353
"esbuild": "0.11.x || 0.12.x"
5454
},
5555
"devDependencies": {
5656
"@testing-library/react": "^12.0.0",
5757
"@types/jsdom": "^16.2.13",
58-
"@types/react": "^17.0.14",
58+
"@types/react": "^17.0.17",
5959
"@types/react-dom": "^17.0.9",
6060
"@types/uuid": "^8.3.1",
6161
"c8": "^7.8.0",
6262
"cross-env": "^7.0.3",
63-
"esbuild": "^0.12.15",
64-
"jsdom": "^16.6.0",
65-
"kcd-scripts": "^11.1.0",
63+
"esbuild": "^0.12.20",
64+
"jsdom": "^16.7.0",
65+
"kcd-scripts": "^11.2.0",
6666
"left-pad": "^1.3.0",
6767
"mdx-test-data": "^1.0.1",
6868
"react": "^17.0.2",

src/__tests__/index.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import React from 'react'
77
import rtl from '@testing-library/react'
88
import leftPad from 'left-pad'
99
import {remarkMdxImages} from 'remark-mdx-images'
10-
import {bundleMDX} from '../index.js'
10+
import {bundleMDX, bundleMDXFile} from '../index.js'
1111
import {getMDXComponent} from '../client.js'
1212

1313
const {render} = rtl
@@ -500,4 +500,22 @@ This is the rest of the content
500500
assert.equal((matter.excerpt ? matter.excerpt : '').trim(), 'Some excerpt')
501501
})
502502

503+
test('specify a file using bundleMDXFile', async () => {
504+
const {frontmatter} = await bundleMDXFile(
505+
path.join(process.cwd(), 'other', 'sample.mdx'),
506+
{
507+
esbuildOptions: options => {
508+
options.loader = {
509+
...options.loader,
510+
'.png': 'dataurl',
511+
}
512+
513+
return options
514+
},
515+
},
516+
)
517+
518+
assert.equal(frontmatter.title, 'Sample')
519+
})
520+
503521
test.run()

src/index.js

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ async function bundleMDX(
2626
esbuildOptions = options => options,
2727
globals = {},
2828
cwd = path.join(process.cwd(), `__mdx_bundler_fake_dir__`),
29-
grayMatterOptions = options => options
29+
grayMatterOptions = options => options,
3030
} = {},
3131
) {
3232
/* c8 ignore start */
@@ -42,8 +42,6 @@ async function bundleMDX(
4242
const [{default: xdmESBuild}] = await Promise.all([
4343
await import('xdm/esbuild.js'),
4444
])
45-
// extract the frontmatter
46-
const matter = grayMatter(mdxSource, grayMatterOptions({}))
4745

4846
const entryPath = path.join(cwd, `./_mdx_bundler_entry_point-${uuid()}.mdx`)
4947

@@ -168,6 +166,24 @@ async function bundleMDX(
168166
minify: true,
169167
})
170168

169+
// Extract the front matter from the source or the entry point
170+
171+
/** @type grayMatter.GrayMatterFile<any> */
172+
let matter
173+
174+
// We have to be a bit specific here to ensure type safety
175+
if (
176+
buildOptions.entryPoints &&
177+
Array.isArray(buildOptions.entryPoints) &&
178+
buildOptions.entryPoints[0] !== entryPath
179+
) {
180+
//The user has replaced the entrypoint, we can assume this means `mdxSource` is empty
181+
182+
matter = grayMatter.read(buildOptions.entryPoints[0], grayMatterOptions({}))
183+
} else {
184+
matter = grayMatter(mdxSource, grayMatterOptions({}))
185+
}
186+
171187
const bundled = await esbuild.build(buildOptions)
172188

173189
if (bundled.outputFiles) {
@@ -179,7 +195,7 @@ async function bundleMDX(
179195
code: `${code};return Component.default;`,
180196
frontmatter: matter.data,
181197
errors: bundled.errors,
182-
matter
198+
matter,
183199
}
184200
}
185201

@@ -198,7 +214,7 @@ async function bundleMDX(
198214
code: `${code};return Component.default;`,
199215
frontmatter: matter.data,
200216
errors: bundled.errors,
201-
matter
217+
matter,
202218
}
203219
}
204220

@@ -207,4 +223,35 @@ async function bundleMDX(
207223
)
208224
}
209225

210-
export {bundleMDX}
226+
/**
227+
*
228+
* @param {string} mdxPath - The file path to bundle.
229+
* @param {import('./types').BundleMDXOptions} options
230+
* @returns
231+
*/
232+
async function bundleMDXFile(
233+
mdxPath,
234+
{
235+
files = {},
236+
xdmOptions = options => options,
237+
esbuildOptions = options => options,
238+
globals = {},
239+
cwd,
240+
grayMatterOptions = options => options,
241+
} = {},
242+
) {
243+
return bundleMDX('', {
244+
files,
245+
xdmOptions,
246+
esbuildOptions: options => {
247+
options.entryPoints = [mdxPath]
248+
249+
return esbuildOptions(options)
250+
},
251+
globals,
252+
cwd: cwd ? cwd : path.dirname(mdxPath),
253+
grayMatterOptions,
254+
})
255+
}
256+
257+
export {bundleMDX, bundleMDXFile}

0 commit comments

Comments
 (0)