Skip to content

Commit 44fd9ca

Browse files
committed
Add support for await in MDX
This likely doesn’t work in your JSX runtime. But if you type `await`, it would currently always be invalid. Now it turns into an `async` function that doesn’t crash. If your runtime supports promises, MDX will support it too. Closes GH-2242.
1 parent 48f0319 commit 44fd9ca

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

packages/mdx/lib/plugin/recma-document.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,9 +602,33 @@ export function recmaDocument(options) {
602602
argument = argument.children[0]
603603
}
604604

605+
let awaitExpression = false
606+
607+
walk(argument, {
608+
enter(node) {
609+
if (
610+
node.type === 'ArrowFunctionExpression' ||
611+
node.type === 'FunctionDeclaration' ||
612+
node.type === 'FunctionExpression'
613+
) {
614+
return this.skip()
615+
}
616+
617+
if (
618+
node.type === 'AwaitExpression' ||
619+
/* c8 ignore next 2 -- can only occur in a function (which then can
620+
* only be async, so skipped it) */
621+
(node.type === 'ForOfStatement' && node.await)
622+
) {
623+
awaitExpression = true
624+
}
625+
}
626+
})
627+
605628
return [
606629
{
607630
type: 'FunctionDeclaration',
631+
async: awaitExpression,
608632
id: {type: 'Identifier', name: '_createMdxContent'},
609633
params: [{type: 'Identifier', name: 'props'}],
610634
body: {

packages/mdx/test/compile.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -973,6 +973,42 @@ test('@mdx-js/mdx: compile', async function (t) {
973973
}
974974
)
975975

976+
await t.test(
977+
'should support an `await` expression in content (GH-2242)',
978+
async function () {
979+
const element = React.createElement(
980+
await run(await compile('{await Promise.resolve(42)}'))
981+
)
982+
983+
try {
984+
// Not supported yet by React, so it throws.
985+
renderToStaticMarkup(element)
986+
assert.fail()
987+
} catch (error) {
988+
assert.match(
989+
String(error),
990+
/Objects are not valid as a React child \(found: \[object Promise]\)/
991+
)
992+
}
993+
}
994+
)
995+
996+
await t.test(
997+
'should not detect `await` inside functions (GH-2242)',
998+
async function () {
999+
const value = `{(function () {
1000+
return 21
1001+
1002+
async function unused() {
1003+
await Promise.resolve(42)
1004+
}
1005+
})()}`
1006+
const element = React.createElement(await run(await compile(value)))
1007+
1008+
assert.equal(renderToStaticMarkup(element), '21')
1009+
}
1010+
)
1011+
9761012
await t.test('should support source maps', async function () {
9771013
const base = new URL('context/', import.meta.url)
9781014
const url = new URL('sourcemap.js', base)

0 commit comments

Comments
 (0)