-
Notifications
You must be signed in to change notification settings - Fork 10.3k
/
Copy pathparser.ts
107 lines (101 loc) · 2.94 KB
/
parser.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import traverse from "@babel/traverse"
import { NodePath } from "@babel/core"
import { JSXOpeningElement } from "@babel/types"
import { parse, ParserOptions } from "@babel/parser"
import babel from "@babel/core"
import { slash } from "gatsby-core-utils"
import { evaluateImageAttributes, hashOptions } from "../babel-helpers"
import { IStaticImageProps } from "../components/static-image.server"
const PARSER_OPTIONS: ParserOptions = {
allowImportExportEverywhere: true,
allowReturnOutsideFunction: true,
allowSuperOutsideMethod: true,
sourceType: `unambiguous`,
plugins: [
`jsx`,
`flow`,
`doExpressions`,
`objectRestSpread`,
[
`decorators`,
{
decoratorsBeforeExport: true,
},
],
`classProperties`,
`classPrivateProperties`,
`classPrivateMethods`,
`exportDefaultFrom`,
`exportNamespaceFrom`,
`asyncGenerators`,
`functionBind`,
`functionSent`,
`dynamicImport`,
`numericSeparator`,
`optionalChaining`,
`importMeta`,
`bigInt`,
`optionalCatchBinding`,
`throwExpressions`,
[
`pipelineOperator`,
{
proposal: `minimal`,
},
],
`nullishCoalescingOperator`,
],
}
export function getBabelParserOptions(filePath: string): ParserOptions {
// Flow and TypeScript plugins can't be enabled simultaneously
if (/\.tsx?/.test(filePath)) {
const { plugins } = PARSER_OPTIONS
return {
...PARSER_OPTIONS,
plugins: (plugins || []).map(plugin =>
plugin === `flow` ? `typescript` : plugin
),
}
}
return PARSER_OPTIONS
}
export function babelParseToAst(
contents: string,
filePath: string
): babel.types.File {
return parse(contents, getBabelParserOptions(filePath))
}
/**
* Traverses the parsed source, looking for StaticImage components.
* Extracts and returns the props from any that are found
*/
export const extractStaticImageProps = (
ast: babel.types.File,
filename: string,
onError?: (prop: string, nodePath: NodePath) => void
): Map<string, IStaticImageProps> => {
const images: Map<string, IStaticImageProps> = new Map()
traverse(ast, {
JSXOpeningElement(nodePath) {
// Is this a StaticImage?
if (
!nodePath
.get(`name`)
.referencesImport(`gatsby-plugin-image`, `StaticImage`)
) {
return
}
const image = evaluateImageAttributes(
// There's a conflict between the definition of NodePath in @babel/core and @babel/traverse
nodePath as unknown as NodePath<JSXOpeningElement>,
onError
) as unknown as IStaticImageProps
// When the image props are the same for multiple StaticImage but they are in different locations
// the hash will be the same then. We need to make sure that the hash is unique.
// The filename should already be normalized but better safe than sorry.
image.filename = slash(filename)
images.set(hashOptions(image), image)
},
})
return images
}