Skip to content

Commit 7a572bf

Browse files
feat: support vfile input (#179)
* feat: support vfile input * handle vfile without path * improve type * fix: handle relative vfile path Co-authored-by: Kent C. Dodds <[email protected]>
1 parent 8f0b681 commit 7a572bf

File tree

4 files changed

+76
-2
lines changed

4 files changed

+76
-2
lines changed

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
"gray-matter": "^4.0.3",
4747
"remark-frontmatter": "^4.0.1",
4848
"remark-mdx-frontmatter": "^1.1.1",
49-
"uuid": "^8.3.2"
49+
"uuid": "^8.3.2",
50+
"vfile": "^5.3.2"
5051
},
5152
"peerDependencies": {
5253
"esbuild": "0.*"

src/__tests__/index.js

+56
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import React from 'react'
66
import rtl from '@testing-library/react'
77
import leftPad from 'left-pad'
88
import {remarkMdxImages} from 'remark-mdx-images'
9+
import {VFile} from 'vfile'
910
import {bundleMDX} from '../index.js'
1011
import {getMDXComponent, getMDXExport} from '../client.js'
1112

@@ -469,6 +470,61 @@ Local Content
469470
)
470471
})
471472

473+
test('should support mdx from VFile', async () => {
474+
const mdxSource = `# Heading`
475+
476+
const vfile = new VFile({value: mdxSource, path: '/data/mdx/my-post.mdx'})
477+
478+
const {code} = await bundleMDX({source: vfile})
479+
480+
const Component = getMDXComponent(code)
481+
482+
const {container} = render(React.createElement(Component))
483+
484+
assert.is(container.innerHTML, '<h1>Heading</h1>')
485+
})
486+
487+
test('should support mdx from VFile without path', async () => {
488+
const mdxSource = `# Heading`
489+
490+
const vfile = new VFile({value: mdxSource})
491+
492+
const {code} = await bundleMDX({source: vfile})
493+
494+
const Component = getMDXComponent(code)
495+
496+
const {container} = render(React.createElement(Component))
497+
498+
assert.is(container.innerHTML, '<h1>Heading</h1>')
499+
})
500+
501+
test('should provide VFile path to plugins', async () => {
502+
const mdxSource = `# Heading`
503+
504+
const vfile = new VFile({value: mdxSource, path: '/data/mdx/my-post.mdx'})
505+
506+
/** @type {import('unified').Plugin} */
507+
function plugin() {
508+
return function transformer(tree, file) {
509+
assert.is(file.path, '/data/mdx/my-post.mdx' )
510+
}
511+
}
512+
513+
const {code} = await bundleMDX({
514+
source: vfile,
515+
mdxOptions(options) {
516+
options.remarkPlugins = [plugin]
517+
return options
518+
},
519+
})
520+
521+
const Component = getMDXComponent(code)
522+
523+
const {container} = render(React.createElement(Component))
524+
525+
assert.is(container.innerHTML, '<h1>Heading</h1>')
526+
})
527+
472528
test('should work with react-dom api', async () => {
473529
const mdxSource = `
474530
import Demo from './demo'

src/index.js

+16
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,29 @@ async function bundleMDX({
5656
)
5757
}
5858

59+
/** @type {(vfile: unknown) => vfile is import('vfile').VFile} */
60+
function isVFile(vfile) {
61+
return typeof vfile === 'object' && vfile !== null && 'value' in vfile
62+
}
63+
5964
if (typeof source === 'string') {
6065
// The user has supplied MDX source.
6166
/** @type any */ // Slight type hack to get the graymatter front matter typed correctly.
6267
const gMatter = grayMatter(source, grayMatterOptions({}))
6368
matter = gMatter
6469
entryPath = path.join(cwd, `./_mdx_bundler_entry_point-${uuid()}.mdx`)
6570
absoluteFiles[entryPath] = source
71+
} else if (isVFile(source)) {
72+
const value = String(source.value)
73+
/** @type any */ // Slight type hack to get the graymatter front matter typed correctly.
74+
const gMatter = grayMatter(value, grayMatterOptions({}))
75+
matter = gMatter
76+
entryPath = source.path
77+
? path.isAbsolute(source.path)
78+
? source.path
79+
: path.join(source.cwd, source.path)
80+
: path.join(cwd, `./_mdx_bundler_entry_point-${uuid()}.mdx`)
81+
absoluteFiles[entryPath] = value
6682
} else if (typeof file === 'string') {
6783
// The user has supplied a file.
6884
/** @type any */ // Slight type hack to get the graymatter front matter typed correctly.

src/types.d.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type {Plugin, BuildOptions, Loader} from 'esbuild'
88
import type {ModuleInfo} from '@fal-works/esbuild-plugin-global-externals'
99
import type {ProcessorOptions} from '@mdx-js/esbuild/lib'
1010
import type {GrayMatterOption, Input, GrayMatterFile} from 'gray-matter'
11+
import type {VFile,VFileOptions} from 'vfile'
1112

1213
type ESBuildOptions = BuildOptions
1314

@@ -19,7 +20,7 @@ export type BundleMDXSource<Frontmatter> = {
1920
/**
2021
* Your MDX source.
2122
*/
22-
source: string
23+
source: string | VFile | VFileOptions
2324
file?: undefined
2425
} & BundleMDXOptions<Frontmatter>
2526

0 commit comments

Comments
 (0)