Skip to content

Commit

Permalink
Add a use strict directive to function bodies
Browse files Browse the repository at this point in the history
  • Loading branch information
wooorm committed Oct 22, 2023
1 parent e525db9 commit 8f3b292
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 17 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 31 additions & 14 deletions packages/mdx/lib/plugin/recma-jsx-build.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,37 @@ export function recmaJsxBuild(options) {
// When compiling to a function body, replace the import that was just
// generated, and get `jsx`, `jsxs`, and `Fragment` from `arguments[0]`
// instead.
if (
outputFormat === 'function-body' &&
tree.body[0] &&
tree.body[0].type === 'ImportDeclaration' &&
typeof tree.body[0].source.value === 'string' &&
/\/jsx-(dev-)?runtime$/.test(tree.body[0].source.value)
) {
tree.body[0] = {
type: 'VariableDeclaration',
kind: 'const',
declarations: specifiersToDeclarations(
tree.body[0].specifiers,
toIdOrMemberExpression(['arguments', 0])
)
if (outputFormat === 'function-body') {
let index = 0

// Skip directives: JS currently only has `use strict`, but Acorn allows
// arbitrary ones.
// Practically things like `use client` could be used?
while (index < tree.body.length) {
const child = tree.body[index]
if ('directive' in child && child.directive) {
index++
} else {
break
}
}

const declaration = tree.body[index]

if (
declaration &&
declaration.type === 'ImportDeclaration' &&
typeof declaration.source.value === 'string' &&
/\/jsx-(dev-)?runtime$/.test(declaration.source.value)
) {
tree.body[index] = {
type: 'VariableDeclaration',
kind: 'const',
declarations: specifiersToDeclarations(
declaration.specifiers,
toIdOrMemberExpression(['arguments', 0])
)
}
}
}
}
Expand Down
8 changes: 8 additions & 0 deletions packages/mdx/lib/plugin/recma-jsx-rewrite.js
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,14 @@ export function recmaJsxRewrite(options) {
}
})
}

if (outputFormat === 'function-body') {
tree.body.unshift({
type: 'ExpressionStatement',
expression: {type: 'Literal', value: 'use strict'},
directive: 'use strict'
})
}
}
}

Expand Down
36 changes: 36 additions & 0 deletions packages/mdx/test/syntax.js
Original file line number Diff line number Diff line change
Expand Up @@ -899,4 +899,40 @@ test('@mdx-js/mdx: syntax: MDX (ESM)', async function (t) {
].join('\n')
)
})

await t.test(
"should add a 'use strict' when generating a `function-body`",
async function () {
assert.equal(
String(await compile('# hi', {outputFormat: 'function-body'})),
[
'/*@jsxRuntime automatic @jsxImportSource react*/',
'"use strict";',
'const {jsx: _jsx} = arguments[0];',
'function _createMdxContent(props) {',
' const _components = {',
' h1: "h1",',
' ...props.components',
' };',
' return _jsx(_components.h1, {',
' children: "hi"',
' });',
'}',
'function MDXContent(props = {}) {',
' const {wrapper: MDXLayout} = props.components || ({});',
' return MDXLayout ? _jsx(MDXLayout, {',
' ...props,',
' children: _jsx(_createMdxContent, {',
' ...props',
' })',
' }) : _createMdxContent(props);',
'}',
'return {',
' default: MDXContent',
'};',
''
].join('\n')
)
}
)
})

0 comments on commit 8f3b292

Please sign in to comment.