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(gatsby-plugin-mdx): support import shorthand syntax #26198

Merged
merged 1 commit into from
Aug 3, 2020
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
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,26 @@ Object {
`;

exports[`regex import scanner syntactic coverage should parse brute force regular case 62 1`] = `
Object {
"input": "import \\"./empty.css\\"",
"result": Object {
"bindings": Array [],
"segments": Array [],
},
}
`;

exports[`regex import scanner syntactic coverage should parse brute force regular case 63 1`] = `
Object {
"input": "import \\"./empty.css\\"; // This happens in the real world",
"result": Object {
"bindings": Array [],
"segments": Array [],
},
}
`;

exports[`regex import scanner syntactic coverage should parse brute force regular case 64 1`] = `
Object {
"input": "import multi as dong, {foo} from 'bar'
import as as x, {from as y} from 'bar'",
Expand Down
59 changes: 58 additions & 1 deletion packages/gatsby-plugin-mdx/utils/__tests__/import-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ function getBruteForceCases() {
import foo from 'bar' // commment containing confusing from "chars"
import foo from 'bar' // import bad from 'imp'
import foo from 'bar'//next to it
import "./empty.css"
import "./empty.css"; // This happens in the real world
`
.trim()
.split(/\n/g)
Expand All @@ -94,7 +96,11 @@ describe(`regex import scanner`, () => {
const output = parseImportBindings(input, true)
const bindings = output.bindings

expect(output.bindings.length).not.toBe(0)
if (input.includes(`empty`)) {
expect(output.bindings.length).toBe(0)
} else {
expect(output.bindings.length).not.toBe(0)
}
// Note: putting everything in the snapshot makes reviews easier
expect({ input, result: output }).toMatchSnapshot()
expect(
Expand Down Expand Up @@ -288,5 +294,56 @@ import {A} from "@your/name"
]
`)
})

it(`double import with shorthand import`, async () => {
// Note: the point of this test is to have two back2back imports clustered
// as one pseudo-node in the ast where the first is the short-hand
// version of `import` that declares no symbols.

const { content } = grayMatter(`
---
title: double test
---

import "./foo.css"
import Events from "@components/events/events"

<Events />
`)

const compiler = mdx.createCompiler()
const fileOpts = { contents: content }
const mdast = await compiler.parse(fileOpts)

const imports = mdast.children.filter(obj => obj.type === `import`)

// Assert the md parser outputs same mdast (update test if this changes)
expect(
imports.map(({ type, value }) => {
return { type, value }
})
).toMatchInlineSnapshot(`
Array [
Object {
"type": "import",
"value": "import \\"./foo.css\\"
import Events from \\"@components/events/events\\"",
},
]
`)

// Take the imports being parsed and feed them to the import parser
expect(parseImportBindings(imports[0].value, true))
.toMatchInlineSnapshot(`
Object {
"bindings": Array [
"Events",
],
"segments": Array [
"Events",
],
}
`)
})
})
})
5 changes: 3 additions & 2 deletions packages/gatsby-plugin-mdx/utils/import-parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
* `from` tail. What's left ought to be a string in the form of
* `id[ as id] [, id[ as id]]`
* (where the brackets represent optional repeating parts). The left-most id
* might also contain star (namespaced import).
* might also contain star (namespaced import). This step also strips
* `import "foo"` shorthand imports.
* The second part will trim and split the string on comma, then each segment
* is split on `as` (in a proper way) and the right-most identifier is returned.
*
Expand All @@ -19,7 +20,7 @@
*/
function parseImportBindings(importCode, returnSegments = false) {
const str = importCode.replace(
/^\s*import|[{},]|\s*from\s*['"][^'"]*?['"].*?$/gm,
/^\s*import\s*['"][^'"]*?['"].*?$|^\s*import|[{},]|\s*from\s*['"][^'"]*?['"].*?$/gm,
` , `
)
const segments = str
Expand Down