Skip to content

Commit

Permalink
feat: add bundleMDXFile to make working with on-disk content easier. (
Browse files Browse the repository at this point in the history
#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.
Arcath authored Aug 13, 2021
1 parent c56b34d commit 325f598
Showing 5 changed files with 99 additions and 24 deletions.
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -593,23 +593,24 @@ const {code} = await bundleMDX(mdxSource, {
})
```

### Replacing the entry point
### bundleMDXFile

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

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

return options
},
})
const {code, frontmatter} = await bundleMDXFile(
'/users/you/site/content/file.mdx',
)
```

`cwd` will be automatically set to the `dirname` of the given file path, you can
still override this. All other options work the same as they do for `bundleMDX`.

### Known Issues

#### Cloudflare Workers
9 changes: 9 additions & 0 deletions other/sample.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
title: 'Sample'
---

import {Sample} from './sample-component'

This is a sample mdx file that should demo mdx-bundlers features.

<Sample />
14 changes: 7 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -40,29 +40,29 @@
"validate": "kcd-scripts validate"
},
"dependencies": {
"@babel/runtime": "^7.14.6",
"@babel/runtime": "^7.15.3",
"@esbuild-plugins/node-resolve": "^0.1.4",
"@fal-works/esbuild-plugin-global-externals": "^2.1.2",
"gray-matter": "^4.0.3",
"remark-frontmatter": "^3.0.0",
"remark-frontmatter": "^4.0.0",
"remark-mdx-frontmatter": "^1.0.1",
"uuid": "^8.3.2",
"xdm": "^1.12.2"
"xdm": "^2.0.0"
},
"peerDependencies": {
"esbuild": "0.11.x || 0.12.x"
},
"devDependencies": {
"@testing-library/react": "^12.0.0",
"@types/jsdom": "^16.2.13",
"@types/react": "^17.0.14",
"@types/react": "^17.0.17",
"@types/react-dom": "^17.0.9",
"@types/uuid": "^8.3.1",
"c8": "^7.8.0",
"cross-env": "^7.0.3",
"esbuild": "^0.12.15",
"jsdom": "^16.6.0",
"kcd-scripts": "^11.1.0",
"esbuild": "^0.12.20",
"jsdom": "^16.7.0",
"kcd-scripts": "^11.2.0",
"left-pad": "^1.3.0",
"mdx-test-data": "^1.0.1",
"react": "^17.0.2",
20 changes: 19 additions & 1 deletion src/__tests__/index.js
Original file line number Diff line number Diff line change
@@ -7,7 +7,7 @@ import React from 'react'
import rtl from '@testing-library/react'
import leftPad from 'left-pad'
import {remarkMdxImages} from 'remark-mdx-images'
import {bundleMDX} from '../index.js'
import {bundleMDX, bundleMDXFile} from '../index.js'
import {getMDXComponent} from '../client.js'

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

test('specify a file using bundleMDXFile', async () => {
const {frontmatter} = await bundleMDXFile(
path.join(process.cwd(), 'other', 'sample.mdx'),
{
esbuildOptions: options => {
options.loader = {
...options.loader,
'.png': 'dataurl',
}

return options
},
},
)

assert.equal(frontmatter.title, 'Sample')
})

test.run()
59 changes: 53 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -26,7 +26,7 @@ async function bundleMDX(
esbuildOptions = options => options,
globals = {},
cwd = path.join(process.cwd(), `__mdx_bundler_fake_dir__`),
grayMatterOptions = options => options
grayMatterOptions = options => options,
} = {},
) {
/* c8 ignore start */
@@ -42,8 +42,6 @@ async function bundleMDX(
const [{default: xdmESBuild}] = await Promise.all([
await import('xdm/esbuild.js'),
])
// extract the frontmatter
const matter = grayMatter(mdxSource, grayMatterOptions({}))

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

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

// Extract the front matter from the source or the entry point

/** @type grayMatter.GrayMatterFile<any> */
let matter

// We have to be a bit specific here to ensure type safety
if (
buildOptions.entryPoints &&
Array.isArray(buildOptions.entryPoints) &&
buildOptions.entryPoints[0] !== entryPath
) {
//The user has replaced the entrypoint, we can assume this means `mdxSource` is empty

matter = grayMatter.read(buildOptions.entryPoints[0], grayMatterOptions({}))
} else {
matter = grayMatter(mdxSource, grayMatterOptions({}))
}

const bundled = await esbuild.build(buildOptions)

if (bundled.outputFiles) {
@@ -179,7 +195,7 @@ async function bundleMDX(
code: `${code};return Component.default;`,
frontmatter: matter.data,
errors: bundled.errors,
matter
matter,
}
}

@@ -198,7 +214,7 @@ async function bundleMDX(
code: `${code};return Component.default;`,
frontmatter: matter.data,
errors: bundled.errors,
matter
matter,
}
}

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

export {bundleMDX}
/**
*
* @param {string} mdxPath - The file path to bundle.
* @param {import('./types').BundleMDXOptions} options
* @returns
*/
async function bundleMDXFile(
mdxPath,
{
files = {},
xdmOptions = options => options,
esbuildOptions = options => options,
globals = {},
cwd,
grayMatterOptions = options => options,
} = {},
) {
return bundleMDX('', {
files,
xdmOptions,
esbuildOptions: options => {
options.entryPoints = [mdxPath]

return esbuildOptions(options)
},
globals,
cwd: cwd ? cwd : path.dirname(mdxPath),
grayMatterOptions,
})
}

export {bundleMDX, bundleMDXFile}

0 comments on commit 325f598

Please sign in to comment.