Skip to content

Commit f77c33f

Browse files
authoredApr 23, 2022
Fix support for baseUrl rewriting import.meta.url
MDX can compile *and* run code, at the same time (called “evaluation”). To evaluate imports and exports in that code, it has to know *from where* to do that, which is a location on the users computer that is not the folder that contains `@mdx-js/mdx` in `node_modules`. That’s what the `baseUrl` option is used for. Previously though, the URL given as `baseUrl` was not used to replace `import.meta.url` in MDX code, which crashed. As they are equivalent, this commit introduces that behavior. Closes GH-2021.
1 parent 109f9c1 commit f77c33f

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed
 

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

+25-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
* Whether to keep `import` (and `export … from`) statements or compile them
2727
* to dynamic `import()` instead.
2828
* @property {string} [baseUrl]
29-
* Resolve relative `import` (and `export … from`) relative to this URL.
29+
* Resolve `import`s (and `export … from`, and `import.meta.url`) relative to
30+
* this URL.
3031
* @property {string} [pragma='React.createElement']
3132
* Pragma for JSX (used in classic runtime).
3233
* @property {string} [pragmaFrag='React.Fragment']
@@ -42,6 +43,7 @@
4243
import {analyze} from 'periscopic'
4344
import {stringifyPosition} from 'unist-util-stringify-position'
4445
import {positionFromEstree} from 'unist-util-position-from-estree'
46+
import {walk} from 'estree-walker'
4547
import {create} from '../util/estree-util-create.js'
4648
import {specifiersToDeclarations} from '../util/estree-util-specifiers-to-declarations.js'
4749
import {declarationToExpression} from '../util/estree-util-declaration-to-expression.js'
@@ -296,6 +298,28 @@ export function recmaDocument(options = {}) {
296298

297299
tree.body = replacement
298300

301+
if (baseUrl) {
302+
walk(tree, {
303+
enter(_node) {
304+
const node = /** @type {Node} */ (_node)
305+
306+
if (
307+
node.type === 'MemberExpression' &&
308+
'object' in node &&
309+
node.object.type === 'MetaProperty' &&
310+
node.property.type === 'Identifier' &&
311+
node.object.meta.name === 'import' &&
312+
node.object.property.name === 'meta' &&
313+
node.property.name === 'url'
314+
) {
315+
/** @type {SimpleLiteral} */
316+
const replacement = {type: 'Literal', value: baseUrl}
317+
this.replace(replacement)
318+
}
319+
}
320+
})
321+
}
322+
299323
/**
300324
* @param {ExportNamedDeclaration|ExportAllDeclaration} node
301325
* @returns {void}

‎packages/mdx/readme.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -360,8 +360,8 @@ return {no, default: MDXContent}
360360

361361
###### `options.baseUrl`
362362

363-
Resolve relative `import` (and `export … from`) from this URL (`string?`,
364-
example: `import.meta.url`).
363+
Resolve `import`s (and `export … from`, and `import.meta.url`) from this URL
364+
(`string?`, example: `import.meta.url`).
365365

366366
Relative specifiers are non-absolute URLs that start with `/`, `./`, or `../`.
367367
For example: `/index.js`, `./folder/file.js`, or `../main.js`.

‎packages/mdx/test/compile.js

+2
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,7 @@ test('compile', async () => {
536536
)
537537
}
538538

539+
console.log('\nnote: the following warning is expected!\n')
539540
assert.equal(
540541
renderToStaticMarkup(
541542
React.createElement(
@@ -545,6 +546,7 @@ test('compile', async () => {
545546
'<a></a>',
546547
'should render if a used member is defined locally (JSX in a function)'
547548
)
549+
console.log('\nnote: the preceding warning is expected!\n')
548550

549551
try {
550552
renderToStaticMarkup(

‎packages/mdx/test/evaluate.js

+11
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,17 @@ test('evaluate', async () => {
290290
'should support an `export all from`, but prefer explicit exports, w/ `useDynamicImport`'
291291
)
292292

293+
assert.equal(
294+
(
295+
await evaluate(
296+
'export const x = new URL("example.png", import.meta.url).href',
297+
{baseUrl: 'https://example.com', ...runtime}
298+
)
299+
).x,
300+
'https://example.com/example.png',
301+
'should support rewriting `import.meta.url` w/ `baseUrl`'
302+
)
303+
293304
assert.throws(
294305
() => {
295306
evaluateSync('export * from "a"', runtime)

1 commit comments

Comments
 (1)

vercel[bot] commented on Apr 23, 2022

@vercel[bot]

Successfully deployed to the following URLs:

mdx – ./

v2.mdxjs.com
mdxjs.com
mdx-mdx.vercel.app
mdx-git-main-mdx.vercel.app

Please sign in to comment.