-
Notifications
You must be signed in to change notification settings - Fork 169
/
transform-react-jsx.ts
63 lines (59 loc) · 2.79 KB
/
transform-react-jsx.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
import ts from 'https://esm.sh/typescript@4.0.5'
import { path } from '../std.ts'
export default function transformReactJsx(sf: ts.SourceFile, node: ts.Node, options: { mode: 'development' | 'production', rewriteImportPath: (importPath: string) => string }): ts.VisitResult<ts.Node> {
if (ts.isJsxOpeningElement(node) || ts.isJsxSelfClosingElement(node)) {
let props = Array.from(node.attributes.properties)
if (node.tagName.getText() === 'Import') {
for (let i = 0; i < props.length; i++) {
const prop = props[i]
if (ts.isJsxAttribute(prop) && prop.name.text === 'from' && prop.initializer && ts.isStringLiteral(prop.initializer)) {
const url = options.rewriteImportPath(prop.initializer.text)
props.splice(i, 1)
props.unshift(
ts.createJsxAttribute(
ts.createIdentifier('from'),
ts.createJsxExpression(undefined, ts.factory.createStringLiteral(url))
),
ts.createJsxAttribute(
ts.createIdentifier('__sourceFile'),
ts.createJsxExpression(undefined, ts.factory.createStringLiteral(path.join(path.dirname(sf.fileName), prop.initializer.text)))
),
ts.createJsxAttribute(
ts.createIdentifier('__importer'),
ts.createJsxExpression(undefined, ts.factory.createStringLiteral(sf.fileName))
)
)
break
}
}
}
if (options.mode === 'development') {
const fileNameAttr = ts.createPropertyAssignment(
'fileName',
ts.createStringLiteral(sf.fileName)
)
const lineNumberAttr = ts.createPropertyAssignment(
'lineNumber',
ts.createNumericLiteral((sf.getLineAndCharacterOfPosition(node.pos).line + 1).toString())
)
const prop = ts.createJsxAttribute(
ts.createIdentifier('__source'),
ts.createJsxExpression(undefined, ts.createObjectLiteral([fileNameAttr, lineNumberAttr]))
)
props.push(prop)
}
if (ts.isJsxSelfClosingElement(node)) {
return ts.createJsxSelfClosingElement(
node.tagName,
node.typeArguments,
ts.createJsxAttributes(props)
)
} else if (ts.isJsxOpeningElement(node)) {
return ts.createJsxOpeningElement(
node.tagName,
node.typeArguments,
ts.createJsxAttributes(props)
)
}
}
}