Fix MDX import and export parsing (#17996)
Co-authored-by: fisker <lionkay@gmail.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
10 files changed
+199
-9
No files matched your search
@@ -0,0 +1,18 @@
|
||||
#### Fix `import` and `export` parsing (#17996 by @kovsu & @fisker)
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
```mdx
|
||||
{/* Input */}
|
||||
- import is a word in lists
|
||||
- export is a word in lists, too!
|
||||
|
||||
{/* Prettier stable */}
|
||||
- import is a word in list
|
||||
s
|
||||
- export is a word in lists, too
|
||||
!
|
||||
|
||||
{/* Prettier main */}
|
||||
- import is a word in lists
|
||||
- export is a word in lists, too!
|
||||
```
|
||||
@@ -57,7 +57,12 @@ function embed(path, options) {
|
||||
// MDX
|
||||
case "import":
|
||||
case "export":
|
||||
return (textToDoc) => textToDoc(node.value, { parser: "babel" });
|
||||
return (textToDoc) =>
|
||||
textToDoc(node.value, {
|
||||
// TODO: Rename this option since it's not used in HTML
|
||||
__onHtmlBindingRoot: (ast) => validateImportExport(ast, node.type),
|
||||
parser: "babel",
|
||||
});
|
||||
case "jsx":
|
||||
return (textToDoc) =>
|
||||
textToDoc(`<$>${node.value}</$>`, {
|
||||
@@ -69,4 +74,22 @@ function embed(path, options) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function validateImportExport(ast, type) {
|
||||
const {
|
||||
program: { body },
|
||||
} = ast;
|
||||
|
||||
// https://github.com/mdx-js/mdx/blob/3430138958c9c0344ecad9d59e0d6b5d72bedae3/packages/remark-mdx/extract-imports-and-exports.js#L16
|
||||
if (
|
||||
!body.every(
|
||||
(node) =>
|
||||
node.type === "ImportDeclaration" ||
|
||||
node.type === "ExportDefaultDeclaration" ||
|
||||
node.type === "ExportNamedDeclaration",
|
||||
)
|
||||
) {
|
||||
throw new Error(`Unexpected '${type}' in MDX.`);
|
||||
}
|
||||
}
|
||||
|
||||
export default embed;
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* modified from https://github.com/mdx-js/mdx/blob/master/packages/mdx
|
||||
* modified from https://github.com/mdx-js/mdx/blob/c91b00c673bcf3e7c28b861fd692b69016026c45/packages/remark-mdx/index.js
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
@@ -31,12 +31,13 @@ const EMPTY_NEWLINE = "\n\n";
|
||||
|
||||
const isImport = (text) => IMPORT_REGEX.test(text);
|
||||
const isExport = (text) => EXPORT_REGEX.test(text);
|
||||
const isImportOrExport = (text) => isImport(text) || isExport(text);
|
||||
|
||||
const tokenizeEsSyntax = (eat, value) => {
|
||||
const index = value.indexOf(EMPTY_NEWLINE);
|
||||
const subvalue = value.slice(0, index);
|
||||
const subvalue = index === -1 ? value : value.slice(0, index);
|
||||
|
||||
if (isExport(subvalue) || isImport(subvalue)) {
|
||||
if (isImportOrExport(subvalue)) {
|
||||
return eat(subvalue)({
|
||||
type: isExport(subvalue) ? "export" : "import",
|
||||
value: subvalue,
|
||||
@@ -44,6 +45,11 @@ const tokenizeEsSyntax = (eat, value) => {
|
||||
}
|
||||
};
|
||||
|
||||
tokenizeEsSyntax.notInBlock = true;
|
||||
|
||||
tokenizeEsSyntax.locator = (value /* , fromIndex*/) =>
|
||||
isImportOrExport(value) ? -1 : 1;
|
||||
|
||||
const tokenizeEsComment = (eat, value) => {
|
||||
const match = ES_COMMENT_REGEX.exec(value);
|
||||
|
||||
@@ -55,10 +61,6 @@ const tokenizeEsComment = (eat, value) => {
|
||||
}
|
||||
};
|
||||
|
||||
/* c8 ignore next 2 */
|
||||
tokenizeEsSyntax.locator = (value /* , fromIndex*/) =>
|
||||
isExport(value) || isImport(value) ? -1 : 1;
|
||||
|
||||
tokenizeEsComment.locator = (value, fromIndex) => value.indexOf("{", fromIndex);
|
||||
|
||||
/** @import {Plugin, Settings} from "unified" */
|
||||
|
||||
@@ -432,7 +432,7 @@ function genericPrint(path, options, print) {
|
||||
case "import":
|
||||
case "export":
|
||||
case "jsx":
|
||||
return node.value;
|
||||
return node.value.trimEnd();
|
||||
case "esComment":
|
||||
return ["{/* ", node.value, " */}"];
|
||||
case "math":
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
|
||||
|
||||
exports[`esm.mdx format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["mdx"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
<!-- https://mdxjs.com/docs/what-is-mdx/#esm -->
|
||||
|
||||
import { External} from './some/place.js'
|
||||
|
||||
export const Local = properties => <span style={{color: 'red'}} {...properties} />
|
||||
|
||||
export const Local = (properties) => (
|
||||
<span style={{ color: "red" }} {...properties} />
|
||||
);
|
||||
|
||||
An <External>external</External> component and a <Local>local one</Local>.
|
||||
|
||||
=====================================output=====================================
|
||||
<!-- https://mdxjs.com/docs/what-is-mdx/#esm -->
|
||||
|
||||
import { External } from "./some/place.js";
|
||||
|
||||
export const Local = (properties) => (
|
||||
<span style={{ color: "red" }} {...properties} />
|
||||
);
|
||||
|
||||
export const Local = (properties) => (
|
||||
<span style={{ color: "red" }} {...properties} />
|
||||
);
|
||||
|
||||
An <External>external</External> component and a <Local>local one</Local>.
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`like-import-declaration.mdx format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["mdx"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
<!-- These are not \`import\`s -->
|
||||
|
||||
import .meta.resolve ( foo)
|
||||
|
||||
import .meta; export {} from "./foo"
|
||||
|
||||
import .meta; import {} from "./foo"
|
||||
|
||||
import ("./foo")
|
||||
|
||||
import {} from "./foo"; export {}
|
||||
|
||||
=====================================output=====================================
|
||||
<!-- These are not \`import\`s -->
|
||||
|
||||
import .meta.resolve ( foo)
|
||||
|
||||
import .meta; export {} from "./foo"
|
||||
|
||||
import .meta; import {} from "./foo"
|
||||
|
||||
import ("./foo")
|
||||
|
||||
import {} from "./foo";
|
||||
export {};
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`list.mdx format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["mdx"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
- import is a word in lists
|
||||
- export is a word in lists, too!
|
||||
|
||||
=====================================output=====================================
|
||||
- import is a word in lists
|
||||
- export is a word in lists, too!
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`paragraph.mdx format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["mdx"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
import is a word
|
||||
|
||||
=====================================output=====================================
|
||||
import is a word
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
|
||||
exports[`snippet: #0 format 1`] = `
|
||||
====================================options=====================================
|
||||
parsers: ["mdx"]
|
||||
printWidth: 80
|
||||
| printWidth
|
||||
=====================================input======================================
|
||||
import is a word
|
||||
=====================================output=====================================
|
||||
import is a word
|
||||
|
||||
================================================================================
|
||||
`;
|
||||
@@ -0,0 +1,11 @@
|
||||
<!-- https://mdxjs.com/docs/what-is-mdx/#esm -->
|
||||
|
||||
import { External} from './some/place.js'
|
||||
|
||||
export const Local = properties => <span style={{color: 'red'}} {...properties} />
|
||||
|
||||
export const Local = (properties) => (
|
||||
<span style={{ color: "red" }} {...properties} />
|
||||
);
|
||||
|
||||
An <External>external</External> component and a <Local>local one</Local>.
|
||||
@@ -0,0 +1,7 @@
|
||||
runFormatTest(
|
||||
{
|
||||
importMeta: import.meta,
|
||||
snippets: ["import is a word"],
|
||||
},
|
||||
["mdx"],
|
||||
);
|
||||
@@ -0,0 +1,11 @@
|
||||
<!-- These are not `import`s -->
|
||||
|
||||
import .meta.resolve ( foo)
|
||||
|
||||
import .meta; export {} from "./foo"
|
||||
|
||||
import .meta; import {} from "./foo"
|
||||
|
||||
import ("./foo")
|
||||
|
||||
import {} from "./foo"; export {}
|
||||
@@ -0,0 +1,2 @@
|
||||
- import is a word in lists
|
||||
- export is a word in lists, too!
|
||||
@@ -0,0 +1 @@
|
||||
import is a word
|
||||
Reference in new issue
Block a user