14
14
* @typedef {import('estree-jsx').JSXIdentifier } JSXIdentifier
15
15
*
16
16
* @typedef Options
17
- * @property {'automatic'|'classic' } [runtime='classic']
17
+ * Configuration (optional).
18
+ *
19
+ * > 👉 **Note**: you can also configure `runtime`, `importSource`, `pragma`,
20
+ * > and `pragmaFrag` from within files through comments.
21
+ * @property {'automatic' | 'classic' } [runtime='classic']
22
+ * Choose the runtime.
23
+ *
24
+ * Comment form: `@jsxRuntime theRuntime`.
18
25
* @property {string } [importSource='react']
26
+ * Place to import `jsx`, `jsxs`, `jsxDEV`, and/or `Fragment` from, when the
27
+ * effective runtime is automatic.
28
+ *
29
+ * Comment form: `@jsxImportSource theSource`.
30
+ *
31
+ * > 👉 **Note**: `/jsx-runtime` or `/jsx-dev-runtime` is appended to this
32
+ * > provided source.
33
+ * > In CJS, that can resolve to a file, as in `theSource/jsx-runtime.js`,
34
+ * > but for ESM an export map needs to be set up to point to files:
35
+ * >
36
+ * > ```js
37
+ * > // …
38
+ * > "exports": {
39
+ * > // …
40
+ * > "./jsx-runtime": "./path/to/jsx-runtime.js",
41
+ * > "./jsx-dev-runtime": "./path/to/jsx-runtime.js"
42
+ * > // …
43
+ * > ```
19
44
* @property {string } [pragma='React.createElement']
45
+ * Identifier or member expression to call when the effective runtime is
46
+ * classic.
47
+ *
48
+ * Comment form: `@jsx identifier`.
20
49
* @property {string } [pragmaFrag='React.Fragment']
50
+ * Identifier or member expression to use as a symbol for fragments when the
51
+ * effective runtime is classic.
52
+ *
53
+ * Comment form: `@jsxFrag identifier`.
21
54
* @property {boolean } [development=false]
55
+ * Import `jsxDEV` from `theSource/jsx-dev-runtime.js` and add location info
56
+ * on where a component originated from.
57
+ *
58
+ * This helps debugging but adds a lot of code that you don’t want in
59
+ * production.
60
+ * Only used in the automatic runtime.
22
61
* @property {string } [filePath]
62
+ * File path to the original source file.
63
+ * Used in the location info when using the automatic runtime with
64
+ * `development: true`.
23
65
*
24
66
* @typedef Annotations
25
- * @property {'automatic'| 'classic' } [jsxRuntime]
67
+ * @property {'automatic' | 'classic' } [jsxRuntime]
26
68
* @property {string } [jsx]
27
69
* @property {string } [jsxFrag]
28
70
* @property {string } [jsxImportSource]
@@ -35,11 +77,17 @@ import {name as isIdentifierName} from 'estree-util-is-identifier-name'
35
77
const regex = / @ ( j s x | j s x F r a g | j s x I m p o r t S o u r c e | j s x R u n t i m e ) \s + ( \S + ) / g
36
78
37
79
/**
38
- * @template {Node} T
39
- * @param {T } tree
80
+ * Turn JSX in `tree` into function calls: `<x />` -> `h('x')`!
81
+ *
82
+ * @template {Node} Tree
83
+ * @param {Tree } tree
84
+ * Tree to transform.
40
85
* @param {Options } [options={}]
41
- * @returns {T }
86
+ * Configuration (optional).
87
+ * @returns {Tree }
88
+ * Given, modified, tree.
42
89
*/
90
+ // To do next major: do not return the given Node.
43
91
export function buildJsx ( tree , options = { } ) {
44
92
let automatic = options . runtime === 'automatic'
45
93
/** @type {Annotations } */
@@ -194,15 +242,15 @@ export function buildJsx(tree, options = {}) {
194
242
}
195
243
}
196
244
197
- /** @type {MemberExpression| Literal| Identifier } */
245
+ /** @type {MemberExpression | Literal | Identifier } */
198
246
let name
199
247
/** @type {Array<Property> } */
200
248
let fields = [ ]
201
249
/** @type {Array<Expression> } */
202
250
const objects = [ ]
203
- /** @type {Array<Expression| SpreadElement> } */
251
+ /** @type {Array<Expression | SpreadElement> } */
204
252
let parameters = [ ]
205
- /** @type {Expression| undefined } */
253
+ /** @type {Expression | undefined } */
206
254
let key
207
255
208
256
// Do the stuff needed for elements.
@@ -215,7 +263,7 @@ export function buildJsx(tree, options = {}) {
215
263
name = create ( name , { type : 'Literal' , value : name . name } )
216
264
}
217
265
218
- /** @type {boolean| undefined } */
266
+ /** @type {boolean | undefined } */
219
267
let spread
220
268
const attributes = node . openingElement . attributes
221
269
let index = - 1
@@ -289,9 +337,9 @@ export function buildJsx(tree, options = {}) {
289
337
objects . push ( { type : 'ObjectExpression' , properties : fields } )
290
338
}
291
339
292
- /** @type {Expression| undefined } */
340
+ /** @type {Expression | undefined } */
293
341
let props
294
- /** @type {MemberExpression| Literal| Identifier } */
342
+ /** @type {MemberExpression | Literal | Identifier } */
295
343
let callee
296
344
297
345
if ( objects . length > 1 ) {
@@ -450,11 +498,11 @@ function toProperty(node) {
450
498
}
451
499
452
500
/**
453
- * @param {JSXMemberExpression| JSXNamespacedName| JSXIdentifier } node
454
- * @returns {MemberExpression| Identifier| Literal }
501
+ * @param {JSXMemberExpression | JSXNamespacedName | JSXIdentifier } node
502
+ * @returns {MemberExpression | Identifier | Literal }
455
503
*/
456
504
function toIdentifier ( node ) {
457
- /** @type {MemberExpression| Identifier| Literal } */
505
+ /** @type {MemberExpression | Identifier | Literal } */
458
506
let replace
459
507
460
508
if ( node . type === 'JSXMemberExpression' ) {
@@ -486,16 +534,16 @@ function toIdentifier(node) {
486
534
487
535
/**
488
536
* @param {string } id
489
- * @returns {Identifier| Literal| MemberExpression }
537
+ * @returns {Identifier | Literal | MemberExpression }
490
538
*/
491
539
function toMemberExpression ( id ) {
492
540
const identifiers = id . split ( '.' )
493
541
let index = - 1
494
- /** @type {Identifier| Literal| MemberExpression| undefined } */
542
+ /** @type {Identifier | Literal | MemberExpression | undefined } */
495
543
let result
496
544
497
545
while ( ++ index < identifiers . length ) {
498
- /** @type {Identifier| Literal } */
546
+ /** @type {Identifier | Literal } */
499
547
const prop = isIdentifierName ( identifiers [ index ] )
500
548
? { type : 'Identifier' , name : identifiers [ index ] }
501
549
: { type : 'Literal' , value : identifiers [ index ] }
0 commit comments