Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix support for baseUrl rewriting import.meta.url #2021

Merged
merged 2 commits into from Apr 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 25 additions & 1 deletion packages/mdx/lib/plugin/recma-document.js
Expand Up @@ -26,7 +26,8 @@
* Whether to keep `import` (and `export … from`) statements or compile them
* to dynamic `import()` instead.
* @property {string} [baseUrl]
* Resolve relative `import` (and `export … from`) relative to this URL.
* Resolve `import`s (and `export … from`, and `import.meta.url`) relative to
* this URL.
* @property {string} [pragma='React.createElement']
* Pragma for JSX (used in classic runtime).
* @property {string} [pragmaFrag='React.Fragment']
Expand All @@ -42,6 +43,7 @@
import {analyze} from 'periscopic'
import {stringifyPosition} from 'unist-util-stringify-position'
import {positionFromEstree} from 'unist-util-position-from-estree'
import {walk} from 'estree-walker'
import {create} from '../util/estree-util-create.js'
import {specifiersToDeclarations} from '../util/estree-util-specifiers-to-declarations.js'
import {declarationToExpression} from '../util/estree-util-declaration-to-expression.js'
Expand Down Expand Up @@ -296,6 +298,28 @@ export function recmaDocument(options = {}) {

tree.body = replacement

if (baseUrl) {
walk(tree, {
enter(_node) {
const node = /** @type {Node} */ (_node)

if (
node.type === 'MemberExpression' &&
'object' in node &&
node.object.type === 'MetaProperty' &&
node.property.type === 'Identifier' &&
node.object.meta.name === 'import' &&
node.object.property.name === 'meta' &&
node.property.name === 'url'
) {
/** @type {SimpleLiteral} */
const replacement = {type: 'Literal', value: baseUrl}
this.replace(replacement)
}
}
})
}

/**
* @param {ExportNamedDeclaration|ExportAllDeclaration} node
* @returns {void}
Expand Down
4 changes: 2 additions & 2 deletions packages/mdx/readme.md
Expand Up @@ -360,8 +360,8 @@ return {no, default: MDXContent}

###### `options.baseUrl`

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

Relative specifiers are non-absolute URLs that start with `/`, `./`, or `../`.
For example: `/index.js`, `./folder/file.js`, or `../main.js`.
Expand Down
2 changes: 2 additions & 0 deletions packages/mdx/test/compile.js
Expand Up @@ -536,6 +536,7 @@ test('compile', async () => {
)
}

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

try {
renderToStaticMarkup(
Expand Down
11 changes: 11 additions & 0 deletions packages/mdx/test/evaluate.js
Expand Up @@ -290,6 +290,17 @@ test('evaluate', async () => {
'should support an `export all from`, but prefer explicit exports, w/ `useDynamicImport`'
)

assert.equal(
(
await evaluate(
'export const x = new URL("example.png", import.meta.url).href',
{baseUrl: 'https://example.com', ...runtime}
)
).x,
'https://example.com/example.png',
'should support rewriting `import.meta.url` w/ `baseUrl`'
)

assert.throws(
() => {
evaluateSync('export * from "a"', runtime)
Expand Down