remove jsx plugin from react (#18484)
Now that the React JSX Babel Plugin is in Babel, remove this code from react
Luna Ruan committed
Apr 3, 2020 at 13:00 UTC
a876808f0a70e37a1a1f78d1e52404adc6cc3895
7 files changed
-2347
packages/babel-plugin-react-jsx/README.md
deleted
-5
@@ -1,5 +0,0 @@
1
-This package is intended to eventually replace the current `@babel/plugin-transform-react-jsx`, changing the JSX transform from targeting `React.createElement(type, props, children)` to `React.jsx(types, props, key)`.
2
-
3
-https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
4
-
5
-**This is experimental and not intended to be used directly.**
packages/babel-plugin-react-jsx/__tests__/TransformJSXToReactJSX-test.js
deleted
-870
@@ -1,870 +0,0 @@
1
-/**
2
- * Copyright (c) Facebook, Inc. and its affiliates.
3
- *
4
- * This source code is licensed under the MIT license found in the
5
- * LICENSE file in the root directory of this source tree.
6
- */
7
-/* eslint-disable quotes */
8
-'use strict';
9
-
10
-const babel = require('@babel/core');
11
-const codeFrame = require('@babel/code-frame');
12
-const {wrap} = require('jest-snapshot-serializer-raw');
13
-
14
-function transform(input, pluginOpts, babelOpts) {
15
- return wrap(
16
- babel.transform(input, {
17
- configFile: false,
18
- sourceType: 'module',
19
- plugins: [
20
- '@babel/plugin-syntax-jsx',
21
- '@babel/plugin-transform-arrow-functions',
22
- ...(pluginOpts && pluginOpts.development
23
- ? [
24
- '@babel/plugin-transform-react-jsx-source',
25
- '@babel/plugin-transform-react-jsx-self',
26
- ]
27
- : []),
28
- [
29
- './packages/babel-plugin-react-jsx',
30
- {
31
- useBuiltIns: true,
32
- useCreateElement: false,
33
- ...pluginOpts,
34
- },
35
- ],
36
- ],
37
- ...babelOpts,
38
- }).code
39
- );
40
-}
41
-
42
-describe('transform react to jsx', () => {
43
- it('auto import pragma overrides regular pragma', () => {
44
- expect(
45
- transform(
46
- `/** @jsxAutoImport defaultExport */
47
- var x = <div><span /></div>
48
- `,
49
- {
50
- autoImport: 'namespace',
51
- importSource: 'foobar',
52
- }
53
- )
54
- ).toMatchSnapshot();
55
- });
56
-
57
- it('import source pragma overrides regular pragma', () => {
58
- expect(
59
- transform(
60
- `/** @jsxImportSource baz */
61
- var x = <div><span /></div>
62
- `,
63
- {
64
- autoImport: 'namespace',
65
- importSource: 'foobar',
66
- }
67
- )
68
- ).toMatchSnapshot();
69
- });
70
-
71
- it('multiple pragmas work', () => {
72
- expect(
73
- transform(
74
- `/** Some comment here
75
- * @jsxImportSource baz
76
- * @jsxAutoImport defaultExport
77
- */
78
- var x = <div><span /></div>
79
- `,
80
- {
81
- autoImport: 'namespace',
82
- importSource: 'foobar',
83
- }
84
- )
85
- ).toMatchSnapshot();
86
- });
87
-
88
- it('throws error when sourceType is module and autoImport is require', () => {
89
- const code = `var x = <div><span /></div>`;
90
- expect(() => {
91
- transform(code, {
92
- autoImport: 'require',
93
- });
94
- }).toThrow(
95
- 'Babel `sourceType` must be set to `script` for autoImport ' +
96
- 'to use `require` syntax. See Babel `sourceType` for details.\n' +
97
- codeFrame.codeFrameColumns(
98
- code,
99
- {start: {line: 1, column: 1}, end: {line: 1, column: 28}},
100
- {highlightCode: true}
101
- )
102
- );
103
- });
104
-
105
- it('throws error when sourceType is script and autoImport is not require', () => {
106
- const code = `var x = <div><span /></div>`;
107
- expect(() => {
108
- transform(
109
- code,
110
- {
111
- autoImport: 'namespace',
112
- },
113
- {sourceType: 'script'}
114
- );
115
- }).toThrow(
116
- 'Babel `sourceType` must be set to `module` for autoImport ' +
117
- 'to use `namespace` syntax. See Babel `sourceType` for details.\n' +
118
- codeFrame.codeFrameColumns(
119
- code,
120
- {start: {line: 1, column: 1}, end: {line: 1, column: 28}},
121
- {highlightCode: true}
122
- )
123
- );
124
- });
125
-
126
- it("auto import that doesn't exist should throw error", () => {
127
- const code = `var x = <div><span /></div>`;
128
- expect(() => {
129
- transform(code, {
130
- autoImport: 'foo',
131
- });
132
- }).toThrow(
133
- 'autoImport must be one of the following: none, require, namespace, defaultExport, namedExports\n' +
134
- codeFrame.codeFrameColumns(
135
- code,
136
- {start: {line: 1, column: 1}, end: {line: 1, column: 28}},
137
- {highlightCode: true}
138
- )
139
- );
140
- });
141
-
142
- it('auto import can specify source', () => {
143
- expect(
144
- transform(`var x = <div><span /></div>`, {
145
- autoImport: 'namespace',
146
- importSource: 'foobar',
147
- })
148
- ).toMatchSnapshot();
149
- });
150
-
151
- it('auto import require', () => {
152
- expect(
153
- transform(
154
- `var x = (
155
- <>
156
- <div>
157
- <div key="1" />
158
- <div key="2" meow="wolf" />
159
- <div key="3" />
160
- <div {...props} key="4" />
161
- </div>
162
- </>
163
- );`,
164
- {
165
- autoImport: 'require',
166
- },
167
- {
168
- sourceType: 'script',
169
- }
170
- )
171
- ).toMatchSnapshot();
172
- });
173
-
174
- it('auto import namespace', () => {
175
- expect(
176
- transform(
177
- `var x = (
178
- <>
179
- <div>
180
- <div key="1" />
181
- <div key="2" meow="wolf" />
182
- <div key="3" />
183
- <div {...props} key="4" />
184
- </div>
185
- </>
186
- );`,
187
- {
188
- autoImport: 'namespace',
189
- }
190
- )
191
- ).toMatchSnapshot();
192
- });
193
-
194
- it('auto import default', () => {
195
- expect(
196
- transform(
197
- `var x = (
198
- <>
199
- <div>
200
- <div key="1" />
201
- <div key="2" meow="wolf" />
202
- <div key="3" />
203
- <div {...props} key="4" />
204
- </div>
205
- </>
206
- );`,
207
- {
208
- autoImport: 'defaultExport',
209
- }
210
- )
211
- ).toMatchSnapshot();
212
- });
213
-
214
- it('auto import named exports', () => {
215
- expect(
216
- transform(
217
- `var x = (
218
- <>
219
- <div>
220
- <div key="1" />
221
- <div key="2" meow="wolf" />
222
- <div key="3" />
223
- <div {...props} key="4" />
224
- </div>
225
- </>
226
- );`,
227
- {
228
- autoImport: 'namedExports',
229
- }
230
- )
231
- ).toMatchSnapshot();
232
- });
233
-
234
- it('auto import with no JSX', () => {
235
- expect(
236
- transform(
237
- `var foo = "<div></div>"`,
238
- {
239
- autoImport: 'require',
240
- },
241
- {
242
- sourceType: 'script',
243
- }
244
- )
245
- ).toMatchSnapshot();
246
- });
247
-
248
- it('complicated scope require', () => {
249
- expect(
250
- transform(
251
- `
252
- const Bar = () => {
253
- const Foo = () => {
254
- const Component = ({thing, ..._react}) => {
255
- if (!thing) {
256
- var _react2 = "something useless";
257
- var b = _react3();
258
- var c = _react5();
259
- var jsx = 1;
260
- var _jsx = 2;
261
- return <div />;
262
- };
263
- return <span />;
264
- };
265
- }
266
- }
267
- `,
268
- {
269
- autoImport: 'require',
270
- },
271
- {
272
- sourceType: 'script',
273
- }
274
- )
275
- ).toMatchSnapshot();
276
- });
277
-
278
- it('complicated scope named exports', () => {
279
- expect(
280
- transform(
281
- `
282
- const Bar = () => {
283
- const Foo = () => {
284
- const Component = ({thing, ..._react}) => {
285
- if (!thing) {
286
- var _react2 = "something useless";
287
- var b = _react3();
288
- var jsx = 1;
289
- var _jsx = 2;
290
- return <div />;
291
- };
292
- return <span />;
293
- };
294
- }
295
- }
296
- `,
297
- {
298
- autoImport: 'namedExports',
299
- }
300
- )
301
- ).toMatchSnapshot();
302
- });
303
-
304
- it('auto import in dev', () => {
305
- expect(
306
- transform(
307
- `var x = (
308
- <>
309
- <div>
310
- <div key="1" />
311
- <div key="2" meow="wolf" />
312
- <div key="3" />
313
- <div {...props} key="4" />
314
- </div>
315
- </>
316
- );`,
317
- {
318
- autoImport: 'namedExports',
319
- development: true,
320
- }
321
- )
322
- ).toMatchSnapshot();
323
- });
324
-
325
- it('auto import none', () => {
326
- expect(
327
- transform(
328
- `var x = (
329
- <>
330
- <div>
331
- <div key="1" />
332
- <div key="2" meow="wolf" />
333
- <div key="3" />
334
- <div {...props} key="4" />
335
- </div>
336
- </>
337
- );`,
338
- {
339
- autoImport: 'none',
340
- }
341
- )
342
- ).toMatchSnapshot();
343
- });
344
-
345
- it('auto import undefined', () => {
346
- expect(
347
- transform(
348
- `var x = (
349
- <>
350
- <div>
351
- <div key="1" />
352
- <div key="2" meow="wolf" />
353
- <div key="3" />
354
- <div {...props} key="4" />
355
- </div>
356
- </>
357
- );`
358
- )
359
- ).toMatchSnapshot();
360
- });
361
-
362
- it('auto import with namespaces already defined', () => {
363
- expect(
364
- transform(
365
- `
366
- import * as _react from "foo";
367
- const react = _react(1);
368
- const _react1 = react;
369
- const _react2 = react;
370
- var x = (
371
- <div>
372
- <div key="1" />
373
- <div key="2" meow="wolf" />
374
- <div key="3" />
375
- <div {...props} key="4" />
376
- </div>
377
- );`,
378
- {
379
- autoImport: 'namespace',
380
- }
381
- )
382
- ).toMatchSnapshot();
383
- });
384
-
385
- it('auto import with react already defined', () => {
386
- expect(
387
- transform(
388
- `
389
- import * as react from "react";
390
- var y = react.createElement("div", {foo: 1});
391
- var x = (
392
- <div>
393
- <div key="1" />
394
- <div key="2" meow="wolf" />
395
- <div key="3" />
396
- <div {...props} key="4" />
397
- </div>
398
- );`,
399
-
400
- {
401
- autoImport: 'namespace',
402
- }
403
- )
404
- ).toMatchSnapshot();
405
- });
406
-
407
- it('fragment with no children', () => {
408
- expect(transform(`var x = <></>`)).toMatchSnapshot();
409
- });
410
-
411
- it('fragments', () => {
412
- expect(transform(`var x = <><div /></>`)).toMatchSnapshot();
413
- });
414
-
415
- it('fragments to set keys', () => {
416
- expect(
417
- transform(`var x = <React.Fragment key="foo"></React.Fragment>`)
418
- ).toMatchSnapshot();
419
- });
420
-
421
- it('React.fragment to set keys and source', () => {
422
- expect(
423
- transform(`var x = <React.Fragment key='foo'></React.Fragment>`, {
424
- development: true,
425
- })
426
- ).toMatchSnapshot();
427
- });
428
-
429
- it('fragments in dev mode (no key and source)', () => {
430
- expect(
431
- transform(`var x = <><div /></>`, {
432
- development: true,
433
- })
434
- ).toMatchSnapshot();
435
- });
436
-
437
- it('nonStatic children', () => {
438
- expect(
439
- transform(
440
- `var x = (
441
- <div>
442
- {[<span key={'0'} />, <span key={'1'} />]}
443
- </div>
444
- );
445
- `,
446
- {
447
- development: true,
448
- }
449
- )
450
- ).toMatchSnapshot();
451
- });
452
-
453
- it('static children', () => {
454
- expect(
455
- transform(
456
- `var x = (
457
- <div>
458
- <span />
459
- {[<span key={'0'} />, <span key={'1'} />]}
460
- </div>
461
- );
462
- `,
463
- {
464
- development: true,
465
- }
466
- )
467
- ).toMatchSnapshot();
468
- });
469
-
470
- it('uses jsxDEV instead of jsx in dev mode', () => {
471
- expect(
472
- transform(`var x = <span propOne="one">Hi</span>`, {development: true})
473
- ).toMatchSnapshot();
474
- });
475
-
476
- it('properly passes in source and self', () => {
477
- expect(
478
- transform(`var x = <div />;`, {development: true})
479
- ).toMatchSnapshot();
480
- });
481
-
482
- it('should properly handle potentially null variables', () => {
483
- expect(
484
- transform(`
485
- var foo = null;
486
- var x = <div {...foo} />;
487
- `)
488
- ).toMatchSnapshot();
489
- });
490
-
491
- it('properly handles keys', () => {
492
- expect(
493
- transform(`var x = (
494
- <div>
495
- <div key="1" />
496
- <div key="2" meow="wolf" />
497
- <div key="3" />
498
- </div>
499
- );`)
500
- ).toMatchSnapshot();
501
- });
502
-
503
- it('uses createElement when the key comes after a spread', () => {
504
- expect(
505
- transform(`var x = (
506
- <div {...props} key="1" foo="bar" />
507
- );`)
508
- ).toMatchSnapshot();
509
- });
510
-
511
- it('uses jsx when the key comes before a spread', () => {
512
- expect(
513
- transform(`var x = (
514
- <div key="1" {...props} foo="bar" />
515
- );`)
516
- ).toMatchSnapshot();
517
- });
518
-
519
- it('should properly handle comments adjacent to children', () => {
520
- expect(
521
- transform(`
522
- var x = (
523
- <div>
524
- {/* A comment at the beginning */}
525
- {/* A second comment at the beginning */}
526
- <span>
527
- {/* A nested comment */}
528
- </span>
529
- {/* A sandwiched comment */}
530
- <br />
531
- {/* A comment at the end */}
532
- {/* A second comment at the end */}
533
- </div>
534
- );
535
- `)
536
- ).toMatchSnapshot();
537
- });
538
-
539
- it('adds appropriate new lines when using spread attribute', () => {
540
- expect(transform(`<Component {...props} sound="moo" />`)).toMatchSnapshot();
541
- });
542
-
543
- it('arrow functions', () => {
544
- expect(
545
- transform(`
546
- var foo = function () {
547
- return () => <this />;
548
- };
549
-
550
- var bar = function () {
551
- return () => <this.foo />;
552
- };
553
-
554
- `)
555
- ).toMatchSnapshot();
556
- });
557
-
558
- it('assignment', () => {
559
- expect(
560
- transform(`var div = <Component {...props} foo="bar" />`)
561
- ).toMatchSnapshot();
562
- });
563
-
564
- it('concatenates adjacent string literals', () => {
565
- expect(
566
- transform(`
567
- var x =
568
- <div>
569
- foo
570
- {"bar"}
571
- baz
572
- <div>
573
- buz
574
- bang
575
- </div>
576
- qux
577
- {null}
578
- quack
579
- </div>
580
- `)
581
- ).toMatchSnapshot();
582
- });
583
-
584
- it('should allow constructor as prop', () => {
585
- expect(transform(`<Component constructor="foo" />;`)).toMatchSnapshot();
586
- });
587
-
588
- it('should allow deeper js namespacing', () => {
589
- expect(
590
- transform(`<Namespace.DeepNamespace.Component />;`)
591
- ).toMatchSnapshot();
592
- });
593
-
594
- it('should allow elements as attributes', () => {
595
- expect(transform(`<div attr=<div /> />`)).toMatchSnapshot();
596
- });
597
-
598
- it('should allow js namespacing', () => {
599
- expect(transform(`<Namespace.Component />;`)).toMatchSnapshot();
600
- });
601
-
602
- it('should allow nested fragments', () => {
603
- expect(
604
- transform(`
605
- <div>
606
- < >
607
- <>
608
- <span>Hello</span>
609
- <span>world</span>
610
- </>
611
- <>
612
- <span>Goodbye</span>
613
- <span>world</span>
614
- </>
615
- </>
616
- </div>
617
- `)
618
- ).toMatchSnapshot();
619
- });
620
-
621
- it('should avoid wrapping in extra parens if not needed', () => {
622
- expect(
623
- transform(`
624
- var x = <div>
625
- <Component />
626
- </div>;
627
-
628
- var x = <div>
629
- {props.children}
630
- </div>;
631
-
632
- var x = <Composite>
633
- {props.children}
634
- </Composite>;
635
-
636
- var x = <Composite>
637
- <Composite2 />
638
- </Composite>;
639
- `)
640
- ).toMatchSnapshot();
641
- });
642
-
643
- it('should convert simple tags', () => {
644
- expect(transform(`var x = <div></div>;`)).toMatchSnapshot();
645
- });
646
-
647
- it('should convert simple text', () => {
648
- expect(transform(`var x = <div>text</div>;`)).toMatchSnapshot();
649
- });
650
-
651
- it('should disallow spread children', () => {
652
- let _error;
653
- const code = `<div>{...children}</div>;`;
654
- try {
655
- transform(code);
656
- } catch (error) {
657
- _error = error;
658
- }
659
- expect(_error).toEqual(
660
- new SyntaxError(
661
- 'unknown: Spread children are not supported in React.' +
662
- '\n' +
663
- codeFrame.codeFrameColumns(
664
- code,
665
- {start: {line: 1, column: 6}, end: {line: 1, column: 19}},
666
- {highlightCode: true}
667
- )
668
- )
669
- );
670
- });
671
-
672
- it('should escape xhtml jsxattribute', () => {
673
- expect(
674
- transform(`
675
- <div id="wôw" />;
676
- <div id="\w" />;
677
- <div id="w < w" />;
678
- `)
679
- ).toMatchSnapshot();
680
- });
681
-
682
- it('should escape xhtml jsxtext', () => {
683
- /* eslint-disable no-irregular-whitespace */
684
- expect(
685
- transform(`
686
- <div>wow</div>;
687
- <div>wôw</div>;
688
-
689
- <div>w & w</div>;
690
- <div>w & w</div>;
691
-
692
- <div>w w</div>;
693
- <div>this should not parse as unicode: \u00a0</div>;
694
- <div>this should parse as nbsp: </div>;
695
- <div>this should parse as unicode: {'\u00a0 '}</div>;
696
-
697
- <div>w < w</div>;
698
- `)
699
- ).toMatchSnapshot();
700
- /*eslint-enable */
701
- });
702
-
703
- it('should handle attributed elements', () => {
704
- expect(
705
- transform(`
706
- var HelloMessage = React.createClass({
707
- render: function() {
708
- return <div>Hello {this.props.name}</div>;
709
- }
710
- });
711
-
712
- React.render(<HelloMessage name={
713
- <span>
714
- Sebastian
715
- </span>
716
- } />, mountNode);
717
- `)
718
- ).toMatchSnapshot();
719
- });
720
-
721
- it('should handle has own property correctly', () => {
722
- expect(
723
- transform(`<hasOwnProperty>testing</hasOwnProperty>;`)
724
- ).toMatchSnapshot();
725
- });
726
-
727
- it('should have correct comma in nested children', () => {
728
- expect(
729
- transform(`
730
- var x = <div>
731
- <div><br /></div>
732
- <Component>{foo}<br />{bar}</Component>
733
- <br />
734
- </div>;
735
- `)
736
- ).toMatchSnapshot();
737
- });
738
-
739
- it('should insert commas after expressions before whitespace', () => {
740
- expect(
741
- transform(`
742
- var x =
743
- <div
744
- attr1={
745
- "foo" + "bar"
746
- }
747
- attr2={
748
- "foo" + "bar" +
749
-
750
- "baz" + "bug"
751
- }
752
- attr3={
753
- "foo" + "bar" +
754
- "baz" + "bug"
755
- }
756
- attr4="baz">
757
- </div>
758
- `)
759
- ).toMatchSnapshot();
760
- });
761
-
762
- it('should not add quotes to identifier names', () => {
763
- expect(
764
- transform(`var e = <F aaa new const var default foo-bar/>;`)
765
- ).toMatchSnapshot();
766
- });
767
-
768
- it('should not strip nbsp even couple with other whitespace', () => {
769
- expect(transform(`<div> </div>;`)).toMatchSnapshot();
770
- });
771
-
772
- it('should not strip tags with a single child of nbsp', () => {
773
- expect(transform(`<div> </div>;`)).toMatchSnapshot();
774
- });
775
-
776
- it('should properly handle comments between props', () => {
777
- expect(
778
- transform(`
779
- var x = (
780
- <div
781
- /* a multi-line
782
- comment */
783
- attr1="foo">
784
- <span // a double-slash comment
785
- attr2="bar"
786
- />
787
- </div>
788
- );
789
- `)
790
- ).toMatchSnapshot();
791
- });
792
-
793
- it('should quote jsx attributes', () => {
794
- expect(
795
- transform(`<button data-value='a value'>Button</button>`)
796
- ).toMatchSnapshot();
797
- });
798
-
799
- it('should support xml namespaces if flag', () => {
800
- expect(
801
- transform('<f:image n:attr />', {throwIfNamespace: false})
802
- ).toMatchSnapshot();
803
- });
804
-
805
- it('should throw error namespaces if not flag', () => {
806
- let _error;
807
- const code = `<f:image />`;
808
- try {
809
- transform(code);
810
- } catch (error) {
811
- _error = error;
812
- }
813
- expect(_error).toEqual(
814
- new SyntaxError(
815
- "unknown: Namespace tags are not supported by default. React's " +
816
- "JSX doesn't support namespace tags. You can turn on the " +
817
- "'throwIfNamespace' flag to bypass this warning." +
818
- '\n' +
819
- codeFrame.codeFrameColumns(
820
- code,
821
- {start: {line: 1, column: 2}, end: {line: 1, column: 9}},
822
- {highlightCode: true}
823
- )
824
- )
825
- );
826
- });
827
-
828
- it('should transform known hyphenated tags', () => {
829
- expect(transform(`<font-face />`)).toMatchSnapshot();
830
- });
831
-
832
- it('wraps props in react spread for first spread attributes', () => {
833
- expect(transform(`<Component {...x} y={2} z />`)).toMatchSnapshot();
834
- });
835
-
836
- it('wraps props in react spread for last spread attributes', () => {
837
- expect(transform(`<Component y={2} z { ... x } />`)).toMatchSnapshot();
838
- });
839
-
840
- it('wraps props in react spread for middle spread attributes', () => {
841
- expect(transform(`<Component y={2} { ... x } z />`)).toMatchSnapshot();
842
- });
843
-
844
- it('useBuiltIns false uses extend instead of Object.assign', () => {
845
- expect(
846
- transform(`<Component y={2} {...x} />`, {useBuiltIns: false})
847
- ).toMatchSnapshot();
848
- });
849
-
850
- it('duplicate children prop should transform into sequence expression with actual children', () => {
851
- expect(
852
- transform(`<Component children={1}>2</Component>`)
853
- ).toMatchSnapshot();
854
- });
855
- it('duplicate children prop should transform into sequence expression with next prop', () => {
856
- expect(
857
- transform(`<Component children={1} foo={3}>2</Component>`)
858
- ).toMatchSnapshot();
859
- });
860
- it('duplicate children props should transform into sequence expression with next prop', () => {
861
- expect(
862
- transform(`<Component children={1} children={4} foo={3}>2</Component>`)
863
- ).toMatchSnapshot();
864
- });
865
- it('duplicate children prop should transform into sequence expression with spread', () => {
866
- expect(
867
- transform(`<Component children={1} {...x}>2</Component>`)
868
- ).toMatchSnapshot();
869
- });
870
-});
packages/babel-plugin-react-jsx/__tests__/__snapshots__/TransformJSXToReactJSX-test.js.snap
deleted
-645
@@ -1,645 +0,0 @@
1
-// Jest Snapshot v1, https://goo.gl/fbAQLP
2
-
3
-exports[`transform react to jsx React.fragment to set keys and source 1`] = `
4
-var _jsxFileName = "";
5
-var x = React.jsxDEV(React.Fragment, {}, "foo", false, {
6
- fileName: _jsxFileName,
7
- lineNumber: 1
8
-}, this);
9
-`;
10
-
11
-exports[`transform react to jsx adds appropriate new lines when using spread attribute 1`] = `
12
-React.jsx(Component, Object.assign({}, props, {
13
- sound: "moo"
14
-}));
15
-`;
16
-
17
-exports[`transform react to jsx arrow functions 1`] = `
18
-var foo = function () {
19
- var _this = this;
20
-
21
- return function () {
22
- return React.jsx(_this, {});
23
- };
24
-};
25
-
26
-var bar = function () {
27
- var _this2 = this;
28
-
29
- return function () {
30
- return React.jsx(_this2.foo, {});
31
- };
32
-};
33
-`;
34
-
35
-exports[`transform react to jsx assignment 1`] = `
36
-var div = React.jsx(Component, Object.assign({}, props, {
37
- foo: "bar"
38
-}));
39
-`;
40
-
41
-exports[`transform react to jsx auto import can specify source 1`] = `
42
-import * as _foobar from "foobar";
43
-
44
-var x = _foobar.jsx("div", {
45
- children: _foobar.jsx("span", {})
46
-});
47
-`;
48
-
49
-exports[`transform react to jsx auto import default 1`] = `
50
-import _default from "react";
51
-
52
-var x = _default.jsx(_default.Fragment, {
53
- children: _default.jsxs("div", {
54
- children: [_default.jsx("div", {}, "1"), _default.jsx("div", {
55
- meow: "wolf"
56
- }, "2"), _default.jsx("div", {}, "3"), _default.createElement("div", Object.assign({}, props, {
57
- key: "4"
58
- }))]
59
- })
60
-});
61
-`;
62
-
63
-exports[`transform react to jsx auto import in dev 1`] = `
64
-import { createElement as _createElement } from "react";
65
-import { jsxDEV as _jsxDEV } from "react";
66
-import { Fragment as _Fragment } from "react";
67
-var _jsxFileName = "";
68
-
69
-var x = _jsxDEV(_Fragment, {
70
- children: _jsxDEV("div", {
71
- children: [_jsxDEV("div", {}, "1", false, {
72
- fileName: _jsxFileName,
73
- lineNumber: 4
74
- }, this), _jsxDEV("div", {
75
- meow: "wolf"
76
- }, "2", false, {
77
- fileName: _jsxFileName,
78
- lineNumber: 5
79
- }, this), _jsxDEV("div", {}, "3", false, {
80
- fileName: _jsxFileName,
81
- lineNumber: 6
82
- }, this), _createElement("div", Object.assign({}, props, {
83
- key: "4",
84
- __source: {
85
- fileName: _jsxFileName,
86
- lineNumber: 7
87
- },
88
- __self: this
89
- }))]
90
- }, undefined, true, {
91
- fileName: _jsxFileName,
92
- lineNumber: 3
93
- }, this)
94
-}, undefined, false);
95
-`;
96
-
97
-exports[`transform react to jsx auto import named exports 1`] = `
98
-import { createElement as _createElement } from "react";
99
-import { jsx as _jsx } from "react";
100
-import { jsxs as _jsxs } from "react";
101
-import { Fragment as _Fragment } from "react";
102
-
103
-var x = _jsx(_Fragment, {
104
- children: _jsxs("div", {
105
- children: [_jsx("div", {}, "1"), _jsx("div", {
106
- meow: "wolf"
107
- }, "2"), _jsx("div", {}, "3"), _createElement("div", Object.assign({}, props, {
108
- key: "4"
109
- }))]
110
- })
111
-});
112
-`;
113
-
114
-exports[`transform react to jsx auto import namespace 1`] = `
115
-import * as _react from "react";
116
-
117
-var x = _react.jsx(_react.Fragment, {
118
- children: _react.jsxs("div", {
119
- children: [_react.jsx("div", {}, "1"), _react.jsx("div", {
120
- meow: "wolf"
121
- }, "2"), _react.jsx("div", {}, "3"), _react.createElement("div", Object.assign({}, props, {
122
- key: "4"
123
- }))]
124
- })
125
-});
126
-`;
127
-
128
-exports[`transform react to jsx auto import none 1`] = `
129
-var x = React.jsx(React.Fragment, {
130
- children: React.jsxs("div", {
131
- children: [React.jsx("div", {}, "1"), React.jsx("div", {
132
- meow: "wolf"
133
- }, "2"), React.jsx("div", {}, "3"), React.createElement("div", Object.assign({}, props, {
134
- key: "4"
135
- }))]
136
- })
137
-});
138
-`;
139
-
140
-exports[`transform react to jsx auto import pragma overrides regular pragma 1`] = `
141
-import _default from "foobar";
142
-
143
-/** @jsxAutoImport defaultExport */
144
-var x = _default.jsx("div", {
145
- children: _default.jsx("span", {})
146
-});
147
-`;
148
-
149
-exports[`transform react to jsx auto import require 1`] = `
150
-var _react = require("react");
151
-
152
-var x = _react.jsx(_react.Fragment, {
153
- children: _react.jsxs("div", {
154
- children: [_react.jsx("div", {}, "1"), _react.jsx("div", {
155
- meow: "wolf"
156
- }, "2"), _react.jsx("div", {}, "3"), _react.createElement("div", Object.assign({}, props, {
157
- key: "4"
158
- }))]
159
- })
160
-});
161
-`;
162
-
163
-exports[`transform react to jsx auto import undefined 1`] = `
164
-var x = React.jsx(React.Fragment, {
165
- children: React.jsxs("div", {
166
- children: [React.jsx("div", {}, "1"), React.jsx("div", {
167
- meow: "wolf"
168
- }, "2"), React.jsx("div", {}, "3"), React.createElement("div", Object.assign({}, props, {
169
- key: "4"
170
- }))]
171
- })
172
-});
173
-`;
174
-
175
-exports[`transform react to jsx auto import with namespaces already defined 1`] = `
176
-import * as _react3 from "react";
177
-import * as _react from "foo";
178
-
179
-const react = _react(1);
180
-
181
-const _react1 = react;
182
-const _react2 = react;
183
-
184
-var x = _react3.jsxs("div", {
185
- children: [_react3.jsx("div", {}, "1"), _react3.jsx("div", {
186
- meow: "wolf"
187
- }, "2"), _react3.jsx("div", {}, "3"), _react3.createElement("div", Object.assign({}, props, {
188
- key: "4"
189
- }))]
190
-});
191
-`;
192
-
193
-exports[`transform react to jsx auto import with no JSX 1`] = `var foo = "<div></div>";`;
194
-
195
-exports[`transform react to jsx auto import with react already defined 1`] = `
196
-import * as _react from "react";
197
-import * as react from "react";
198
-var y = react.createElement("div", {
199
- foo: 1
200
-});
201
-
202
-var x = _react.jsxs("div", {
203
- children: [_react.jsx("div", {}, "1"), _react.jsx("div", {
204
- meow: "wolf"
205
- }, "2"), _react.jsx("div", {}, "3"), _react.createElement("div", Object.assign({}, props, {
206
- key: "4"
207
- }))]
208
-});
209
-`;
210
-
211
-exports[`transform react to jsx complicated scope named exports 1`] = `
212
-import { jsx as _jsx2 } from "react";
213
-
214
-const Bar = function () {
215
- const Foo = function () {
216
- const Component = function ({
217
- thing,
218
- ..._react
219
- }) {
220
- if (!thing) {
221
- var _react2 = "something useless";
222
-
223
- var b = _react3();
224
-
225
- var jsx = 1;
226
- var _jsx = 2;
227
- return _jsx2("div", {});
228
- }
229
-
230
- ;
231
- return _jsx2("span", {});
232
- };
233
- };
234
-};
235
-`;
236
-
237
-exports[`transform react to jsx complicated scope require 1`] = `
238
-var _react4 = require("react");
239
-
240
-const Bar = function () {
241
- const Foo = function () {
242
- const Component = function ({
243
- thing,
244
- ..._react
245
- }) {
246
- if (!thing) {
247
- var _react2 = "something useless";
248
-
249
- var b = _react3();
250
-
251
- var c = _react5();
252
-
253
- var jsx = 1;
254
- var _jsx = 2;
255
- return _react4.jsx("div", {});
256
- }
257
-
258
- ;
259
- return _react4.jsx("span", {});
260
- };
261
- };
262
-};
263
-`;
264
-
265
-exports[`transform react to jsx concatenates adjacent string literals 1`] = `
266
-var x = React.jsxs("div", {
267
- children: ["foo", "bar", "baz", React.jsx("div", {
268
- children: "buz bang"
269
- }), "qux", null, "quack"]
270
-});
271
-`;
272
-
273
-exports[`transform react to jsx duplicate children prop should transform into sequence expression with actual children 1`] = `
274
-React.jsx(Component, {
275
- children: (1, "2")
276
-});
277
-`;
278
-
279
-exports[`transform react to jsx duplicate children prop should transform into sequence expression with next prop 1`] = `
280
-React.jsx(Component, {
281
- foo: (1, 3),
282
- children: "2"
283
-});
284
-`;
285
-
286
-exports[`transform react to jsx duplicate children prop should transform into sequence expression with spread 1`] = `
287
-React.jsx(Component, Object.assign({}, (1, x), {
288
- children: "2"
289
-}));
290
-`;
291
-
292
-exports[`transform react to jsx duplicate children props should transform into sequence expression with next prop 1`] = `
293
-React.jsx(Component, {
294
- foo: (1, 4, 3),
295
- children: "2"
296
-});
297
-`;
298
-
299
-exports[`transform react to jsx fragment with no children 1`] = `var x = React.jsx(React.Fragment, {});`;
300
-
301
-exports[`transform react to jsx fragments 1`] = `
302
-var x = React.jsx(React.Fragment, {
303
- children: React.jsx("div", {})
304
-});
305
-`;
306
-
307
-exports[`transform react to jsx fragments in dev mode (no key and source) 1`] = `
308
-var _jsxFileName = "";
309
-var x = React.jsxDEV(React.Fragment, {
310
- children: React.jsxDEV("div", {}, undefined, false, {
311
- fileName: _jsxFileName,
312
- lineNumber: 1
313
- }, this)
314
-}, undefined, false);
315
-`;
316
-
317
-exports[`transform react to jsx fragments to set keys 1`] = `var x = React.jsx(React.Fragment, {}, "foo");`;
318
-
319
-exports[`transform react to jsx import source pragma overrides regular pragma 1`] = `
320
-import * as _baz from "baz";
321
-
322
-/** @jsxImportSource baz */
323
-var x = _baz.jsx("div", {
324
- children: _baz.jsx("span", {})
325
-});
326
-`;
327
-
328
-exports[`transform react to jsx multiple pragmas work 1`] = `
329
-import _default from "baz";
330
-
331
-/** Some comment here
332
- * @jsxImportSource baz
333
- * @jsxAutoImport defaultExport
334
- */
335
-var x = _default.jsx("div", {
336
- children: _default.jsx("span", {})
337
-});
338
-`;
339
-
340
-exports[`transform react to jsx nonStatic children 1`] = `
341
-var _jsxFileName = "";
342
-var x = React.jsxDEV("div", {
343
- children: [React.jsxDEV("span", {}, '0', false, {
344
- fileName: _jsxFileName,
345
- lineNumber: 3
346
- }, this), React.jsxDEV("span", {}, '1', false, {
347
- fileName: _jsxFileName,
348
- lineNumber: 3
349
- }, this)]
350
-}, undefined, false, {
351
- fileName: _jsxFileName,
352
- lineNumber: 2
353
-}, this);
354
-`;
355
-
356
-exports[`transform react to jsx properly handles keys 1`] = `
357
-var x = React.jsxs("div", {
358
- children: [React.jsx("div", {}, "1"), React.jsx("div", {
359
- meow: "wolf"
360
- }, "2"), React.jsx("div", {}, "3")]
361
-});
362
-`;
363
-
364
-exports[`transform react to jsx properly passes in source and self 1`] = `
365
-var _jsxFileName = "";
366
-var x = React.jsxDEV("div", {}, undefined, false, {
367
- fileName: _jsxFileName,
368
- lineNumber: 1
369
-}, this);
370
-`;
371
-
372
-exports[`transform react to jsx should allow constructor as prop 1`] = `
373
-React.jsx(Component, {
374
- constructor: "foo"
375
-});
376
-`;
377
-
378
-exports[`transform react to jsx should allow deeper js namespacing 1`] = `React.jsx(Namespace.DeepNamespace.Component, {});`;
379
-
380
-exports[`transform react to jsx should allow elements as attributes 1`] = `
381
-React.jsx("div", {
382
- attr: React.jsx("div", {})
383
-});
384
-`;
385
-
386
-exports[`transform react to jsx should allow js namespacing 1`] = `React.jsx(Namespace.Component, {});`;
387
-
388
-exports[`transform react to jsx should allow nested fragments 1`] = `
389
-React.jsx("div", {
390
- children: React.jsxs(React.Fragment, {
391
- children: [React.jsxs(React.Fragment, {
392
- children: [React.jsx("span", {
393
- children: "Hello"
394
- }), React.jsx("span", {
395
- children: "world"
396
- })]
397
- }), React.jsxs(React.Fragment, {
398
- children: [React.jsx("span", {
399
- children: "Goodbye"
400
- }), React.jsx("span", {
401
- children: "world"
402
- })]
403
- })]
404
- })
405
-});
406
-`;
407
-
408
-exports[`transform react to jsx should avoid wrapping in extra parens if not needed 1`] = `
409
-var x = React.jsx("div", {
410
- children: React.jsx(Component, {})
411
-});
412
-var x = React.jsx("div", {
413
- children: props.children
414
-});
415
-var x = React.jsx(Composite, {
416
- children: props.children
417
-});
418
-var x = React.jsx(Composite, {
419
- children: React.jsx(Composite2, {})
420
-});
421
-`;
422
-
423
-exports[`transform react to jsx should convert simple tags 1`] = `var x = React.jsx("div", {});`;
424
-
425
-exports[`transform react to jsx should convert simple text 1`] = `
426
-var x = React.jsx("div", {
427
- children: "text"
428
-});
429
-`;
430
-
431
-exports[`transform react to jsx should escape xhtml jsxattribute 1`] = `
432
-React.jsx("div", {
433
- id: "w\\xF4w"
434
-});
435
-React.jsx("div", {
436
- id: "w"
437
-});
438
-React.jsx("div", {
439
- id: "w < w"
440
-});
441
-`;
442
-
443
-exports[`transform react to jsx should escape xhtml jsxtext 1`] = `
444
-React.jsx("div", {
445
- children: "wow"
446
-});
447
-React.jsx("div", {
448
- children: "w\\xF4w"
449
-});
450
-React.jsx("div", {
451
- children: "w & w"
452
-});
453
-React.jsx("div", {
454
- children: "w & w"
455
-});
456
-React.jsx("div", {
457
- children: "w \\xA0 w"
458
-});
459
-React.jsx("div", {
460
- children: "this should not parse as unicode: \\xA0"
461
-});
462
-React.jsx("div", {
463
- children: "this should parse as nbsp: \\xA0 "
464
-});
465
-React.jsxs("div", {
466
- children: ["this should parse as unicode: ", ' ']
467
-});
468
-React.jsx("div", {
469
- children: "w < w"
470
-});
471
-`;
472
-
473
-exports[`transform react to jsx should handle attributed elements 1`] = `
474
-var HelloMessage = React.createClass({
475
- render: function () {
476
- return React.jsxs("div", {
477
- children: ["Hello ", this.props.name]
478
- });
479
- }
480
-});
481
-React.render(React.jsx(HelloMessage, {
482
- name: React.jsx("span", {
483
- children: "Sebastian"
484
- })
485
-}), mountNode);
486
-`;
487
-
488
-exports[`transform react to jsx should handle has own property correctly 1`] = `
489
-React.jsx("hasOwnProperty", {
490
- children: "testing"
491
-});
492
-`;
493
-
494
-exports[`transform react to jsx should have correct comma in nested children 1`] = `
495
-var x = React.jsxs("div", {
496
- children: [React.jsx("div", {
497
- children: React.jsx("br", {})
498
- }), React.jsxs(Component, {
499
- children: [foo, React.jsx("br", {}), bar]
500
- }), React.jsx("br", {})]
501
-});
502
-`;
503
-
504
-exports[`transform react to jsx should insert commas after expressions before whitespace 1`] = `
505
-var x = React.jsx("div", {
506
- attr1: "foo" + "bar",
507
- attr2: "foo" + "bar" + "baz" + "bug",
508
- attr3: "foo" + "bar" + "baz" + "bug",
509
- attr4: "baz"
510
-});
511
-`;
512
-
513
-exports[`transform react to jsx should not add quotes to identifier names 1`] = `
514
-var e = React.jsx(F, {
515
- aaa: true,
516
- new: true,
517
- const: true,
518
- var: true,
519
- default: true,
520
- "foo-bar": true
521
-});
522
-`;
523
-
524
-exports[`transform react to jsx should not strip nbsp even couple with other whitespace 1`] = `
525
-React.jsx("div", {
526
- children: "\\xA0 "
527
-});
528
-`;
529
-
530
-exports[`transform react to jsx should not strip tags with a single child of nbsp 1`] = `
531
-React.jsx("div", {
532
- children: "\\xA0"
533
-});
534
-`;
535
-
536
-exports[`transform react to jsx should properly handle comments adjacent to children 1`] = `
537
-var x = React.jsxs("div", {
538
- children: [React.jsx("span", {}), React.jsx("br", {})]
539
-});
540
-`;
541
-
542
-exports[`transform react to jsx should properly handle comments between props 1`] = `
543
-var x = React.jsx("div", {
544
- /* a multi-line
545
- comment */
546
- attr1: "foo",
547
- children: React.jsx("span", {
548
- // a double-slash comment
549
- attr2: "bar"
550
- })
551
-});
552
-`;
553
-
554
-exports[`transform react to jsx should properly handle potentially null variables 1`] = `
555
-var foo = null;
556
-var x = React.jsx("div", Object.assign({}, foo));
557
-`;
558
-
559
-exports[`transform react to jsx should quote jsx attributes 1`] = `
560
-React.jsx("button", {
561
- "data-value": "a value",
562
- children: "Button"
563
-});
564
-`;
565
-
566
-exports[`transform react to jsx should support xml namespaces if flag 1`] = `
567
-React.jsx("f:image", {
568
- "n:attr": true
569
-});
570
-`;
571
-
572
-exports[`transform react to jsx should transform known hyphenated tags 1`] = `React.jsx("font-face", {});`;
573
-
574
-exports[`transform react to jsx static children 1`] = `
575
-var _jsxFileName = "";
576
-var x = React.jsxDEV("div", {
577
- children: [React.jsxDEV("span", {}, undefined, false, {
578
- fileName: _jsxFileName,
579
- lineNumber: 3
580
- }, this), [React.jsxDEV("span", {}, '0', false, {
581
- fileName: _jsxFileName,
582
- lineNumber: 4
583
- }, this), React.jsxDEV("span", {}, '1', false, {
584
- fileName: _jsxFileName,
585
- lineNumber: 4
586
- }, this)]]
587
-}, undefined, true, {
588
- fileName: _jsxFileName,
589
- lineNumber: 2
590
-}, this);
591
-`;
592
-
593
-exports[`transform react to jsx useBuiltIns false uses extend instead of Object.assign 1`] = `
594
-function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
595
-
596
-React.jsx(Component, _extends({
597
- y: 2
598
-}, x));
599
-`;
600
-
601
-exports[`transform react to jsx uses createElement when the key comes after a spread 1`] = `
602
-var x = React.createElement("div", Object.assign({}, props, {
603
- key: "1",
604
- foo: "bar"
605
-}));
606
-`;
607
-
608
-exports[`transform react to jsx uses jsx when the key comes before a spread 1`] = `
609
-var x = React.jsx("div", Object.assign({}, props, {
610
- foo: "bar"
611
-}), "1");
612
-`;
613
-
614
-exports[`transform react to jsx uses jsxDEV instead of jsx in dev mode 1`] = `
615
-var _jsxFileName = "";
616
-var x = React.jsxDEV("span", {
617
- propOne: "one",
618
- children: "Hi"
619
-}, undefined, false, {
620
- fileName: _jsxFileName,
621
- lineNumber: 1
622
-}, this);
623
-`;
624
-
625
-exports[`transform react to jsx wraps props in react spread for first spread attributes 1`] = `
626
-React.jsx(Component, Object.assign({}, x, {
627
- y: 2,
628
- z: true
629
-}));
630
-`;
631
-
632
-exports[`transform react to jsx wraps props in react spread for last spread attributes 1`] = `
633
-React.jsx(Component, Object.assign({
634
- y: 2,
635
- z: true
636
-}, x));
637
-`;
638
-
639
-exports[`transform react to jsx wraps props in react spread for middle spread attributes 1`] = `
640
-React.jsx(Component, Object.assign({
641
- y: 2
642
-}, x, {
643
- z: true
644
-}));
645
-`;
packages/babel-plugin-react-jsx/index.js
deleted
-3
@@ -1,3 +0,0 @@
1
-'use strict';
2
-
3
-module.exports = require('./src/TransformJSXToReactBabelPlugin');
packages/babel-plugin-react-jsx/npm/index.js
deleted
-7
@@ -1,7 +0,0 @@
1
-'use strict';
2
-
3
-if (process.env.NODE_ENV === 'production') {
4
- module.exports = require('./cjs/react-jsx-babel.production.min.js');
5
-} else {
6
- module.exports = require('./cjs/react-jsx-babel.development.js');
7
-}
packages/babel-plugin-react-jsx/package.json
deleted
-18
@@ -1,18 +0,0 @@
1
-{
2
- "name": "babel-plugin-react-jsx",
3
- "version": "0.1.0",
4
- "private": true,
5
- "description": "@babel/plugin-transform-react-jsx",
6
- "main": "index.js",
7
- "dependencies": {
8
- "@babel/helper-module-imports": "^7.0.0",
9
- "esutils": "^2.0.0"
10
- },
11
- "files": [
12
- "README.md",
13
- "index.js",
14
- "build-info.json",
15
- "cjs/",
16
- "umd/"
17
- ]
18
-}
packages/babel-plugin-react-jsx/src/TransformJSXToReactBabelPlugin.js
deleted
-799
@@ -1,799 +0,0 @@
1
-// MIT License
2
-
3
-// Copyright (c) 2014-present Sebastian McKenzie and other contributors
4
-
5
-// Permission is hereby granted, free of charge, to any person obtaining
6
-// a copy of this software and associated documentation files (the
7
-// "Software"), to deal in the Software without restriction, including
8
-// without limitation the rights to use, copy, modify, merge, publish,
9
-// distribute, sublicense, and/or sell copies of the Software, and to
10
-// permit persons to whom the Software is furnished to do so, subject to
11
-// the following conditions:
12
-
13
-// The above copyright notice and this permission notice shall be
14
-// included in all copies or substantial portions of the Software.
15
-
16
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
-// © 2019 GitHub, Inc.
24
-'use strict';
25
-
26
-const esutils = require('esutils');
27
-const {
28
- isModule,
29
- addNamespace,
30
- addNamed,
31
- addDefault,
32
-} = require('@babel/helper-module-imports');
33
-
34
-// These are all the valid auto import types (under the config autoImport)
35
-// that a user can specific
36
-const IMPORT_TYPES = {
37
- none: 'none', // default option. Will not import anything
38
- require: 'require', // var _react = require("react");
39
- namespace: 'namespace', // import * as _react from "react";
40
- defaultExport: 'defaultExport', // import _default from "react";
41
- namedExports: 'namedExports', // import { jsx } from "react";
42
-};
43
-
44
-const JSX_AUTO_IMPORT_ANNOTATION_REGEX = /\*?\s*@jsxAutoImport\s+([^\s]+)/;
45
-const JSX_IMPORT_SOURCE_ANNOTATION_REGEX = /\*?\s*@jsxImportSource\s+([^\s]+)/;
46
-
47
-// We want to use React.createElement, even in the case of
48
-// jsx, for <div {...props} key={key} /> to distinguish it
49
-// from <div key={key} {...props} />. This is an intermediary
50
-// step while we deprecate key spread from props. Afterwards,
51
-// we will remove createElement entirely
52
-function shouldUseCreateElement(path, types) {
53
- const openingPath = path.get('openingElement');
54
- const attributes = openingPath.node.attributes;
55
-
56
- let seenPropsSpread = false;
57
- for (let i = 0; i < attributes.length; i++) {
58
- const attr = attributes[i];
59
- if (
60
- seenPropsSpread &&
61
- types.isJSXAttribute(attr) &&
62
- attr.name.name === 'key'
63
- ) {
64
- return true;
65
- } else if (types.isJSXSpreadAttribute(attr)) {
66
- seenPropsSpread = true;
67
- }
68
- }
69
- return false;
70
-}
71
-
72
-function helper(babel, opts) {
73
- const {types: t} = babel;
74
-
75
- const visitor = {};
76
-
77
- visitor.JSXNamespacedName = function(path, state) {
78
- const throwIfNamespace =
79
- state.opts.throwIfNamespace === undefined
80
- ? true
81
- : !!state.opts.throwIfNamespace;
82
- if (throwIfNamespace) {
83
- throw path.buildCodeFrameError(
84
- `Namespace tags are not supported by default. React's JSX doesn't support namespace tags. \
85
-You can turn on the 'throwIfNamespace' flag to bypass this warning.`,
86
- );
87
- }
88
- };
89
-
90
- visitor.JSXSpreadChild = function(path) {
91
- throw path.buildCodeFrameError(
92
- 'Spread children are not supported in React.',
93
- );
94
- };
95
-
96
- visitor.JSXElement = {
97
- exit(path, file) {
98
- let callExpr;
99
- if (shouldUseCreateElement(path, t)) {
100
- callExpr = buildCreateElementCall(path, file);
101
- } else {
102
- callExpr = buildJSXElementCall(path, file);
103
- }
104
-
105
- if (callExpr) {
106
- path.replaceWith(t.inherits(callExpr, path.node));
107
- }
108
- },
109
- };
110
-
111
- visitor.JSXFragment = {
112
- exit(path, file) {
113
- if (opts.compat) {
114
- throw path.buildCodeFrameError(
115
- 'Fragment tags are only supported in React 16 and up.',
116
- );
117
- }
118
- const callExpr = buildJSXFragmentCall(path, file);
119
-
120
- if (callExpr) {
121
- path.replaceWith(t.inherits(callExpr, path.node));
122
- }
123
- },
124
- };
125
-
126
- return visitor;
127
-
128
- function convertJSXIdentifier(node, parent) {
129
- if (t.isJSXIdentifier(node)) {
130
- if (node.name === 'this' && t.isReferenced(node, parent)) {
131
- return t.thisExpression();
132
- } else if (esutils.keyword.isIdentifierNameES6(node.name)) {
133
- node.type = 'Identifier';
134
- } else {
135
- return t.stringLiteral(node.name);
136
- }
137
- } else if (t.isJSXMemberExpression(node)) {
138
- return t.memberExpression(
139
- convertJSXIdentifier(node.object, node),
140
- convertJSXIdentifier(node.property, node),
141
- );
142
- } else if (t.isJSXNamespacedName(node)) {
143
- /**
144
- * If there is flag "throwIfNamespace"
145
- * print XMLNamespace like string literal
146
- */
147
- return t.stringLiteral(`${node.namespace.name}:${node.name.name}`);
148
- }
149
-
150
- return node;
151
- }
152
-
153
- function convertAttributeValue(node) {
154
- if (t.isJSXExpressionContainer(node)) {
155
- return node.expression;
156
- } else {
157
- return node;
158
- }
159
- }
160
-
161
- function convertAttribute(node, duplicateChildren) {
162
- let value = convertAttributeValue(node.value || t.booleanLiteral(true));
163
-
164
- if (t.isStringLiteral(value) && !t.isJSXExpressionContainer(node.value)) {
165
- value.value = value.value.replace(/\n\s+/g, ' ');
166
-
167
- // "raw" JSXText should not be used from a StringLiteral because it needs to be escaped.
168
- if (value.extra && value.extra.raw) {
169
- delete value.extra.raw;
170
- }
171
- }
172
- if (duplicateChildren && duplicateChildren.length > 0) {
173
- value = t.sequenceExpression([...duplicateChildren, value]);
174
- }
175
-
176
- if (t.isJSXNamespacedName(node.name)) {
177
- node.name = t.stringLiteral(
178
- node.name.namespace.name + ':' + node.name.name.name,
179
- );
180
- } else if (esutils.keyword.isIdentifierNameES6(node.name.name)) {
181
- node.name.type = 'Identifier';
182
- } else {
183
- node.name = t.stringLiteral(node.name.name);
184
- }
185
-
186
- return t.inherits(t.objectProperty(node.name, value), node);
187
- }
188
-
189
- // Builds JSX into:
190
- // Production: React.jsx(type, arguments, key)
191
- // Development: React.jsxDEV(type, arguments, key, isStaticChildren, source, self)
192
- function buildJSXElementCall(path, file) {
193
- if (opts.filter && !opts.filter(path.node, file)) {
194
- return;
195
- }
196
-
197
- const openingPath = path.get('openingElement');
198
- openingPath.parent.children = t.react.buildChildren(openingPath.parent);
199
-
200
- const tagExpr = convertJSXIdentifier(
201
- openingPath.node.name,
202
- openingPath.node,
203
- );
204
- const args = [];
205
-
206
- let tagName;
207
- if (t.isIdentifier(tagExpr)) {
208
- tagName = tagExpr.name;
209
- } else if (t.isLiteral(tagExpr)) {
210
- tagName = tagExpr.value;
211
- }
212
-
213
- const state = {
214
- tagExpr: tagExpr,
215
- tagName: tagName,
216
- args: args,
217
- };
218
-
219
- if (opts.pre) {
220
- opts.pre(state, file);
221
- }
222
-
223
- let attribs = [];
224
- let key;
225
- let source;
226
- let self;
227
-
228
- // for React.jsx, key, __source (dev), and __self (dev) is passed in as
229
- // a separate argument rather than in the args object. We go through the
230
- // props and filter out these three keywords so we can pass them in
231
- // as separate arguments later
232
- for (let i = 0; i < openingPath.node.attributes.length; i++) {
233
- const attr = openingPath.node.attributes[i];
234
- if (t.isJSXAttribute(attr) && t.isJSXIdentifier(attr.name)) {
235
- if (attr.name.name === 'key') {
236
- key = convertAttribute(attr).value;
237
- } else if (attr.name.name === '__source') {
238
- source = convertAttribute(attr).value;
239
- } else if (attr.name.name === '__self') {
240
- self = convertAttribute(attr).value;
241
- } else {
242
- attribs.push(attr);
243
- }
244
- } else {
245
- attribs.push(attr);
246
- }
247
- }
248
-
249
- if (attribs.length || path.node.children.length) {
250
- attribs = buildJSXOpeningElementAttributes(
251
- attribs,
252
- file,
253
- path.node.children,
254
- );
255
- } else {
256
- // attributes should never be null
257
- attribs = t.objectExpression([]);
258
- }
259
-
260
- args.push(attribs);
261
-
262
- if (!file.opts.development) {
263
- if (key !== undefined) {
264
- args.push(key);
265
- }
266
- } else {
267
- // isStaticChildren, __source, and __self are only used in development
268
- args.push(
269
- key === undefined ? t.identifier('undefined') : key,
270
- t.booleanLiteral(path.node.children.length > 1),
271
- source === undefined ? t.identifier('undefined') : source,
272
- self === undefined ? t.identifier('undefined') : self,
273
- );
274
- }
275
-
276
- if (opts.post) {
277
- opts.post(state, file);
278
- }
279
-
280
- return (
281
- state.call ||
282
- t.callExpression(
283
- path.node.children.length > 1 ? state.staticCallee : state.callee,
284
- args,
285
- )
286
- );
287
- }
288
-
289
- function isChildrenProp(prop) {
290
- return (
291
- t.isJSXAttribute(prop) &&
292
- t.isJSXIdentifier(prop.name) &&
293
- prop.name.name === 'children'
294
- );
295
- }
296
-
297
- // Builds props for React.jsx. This function adds children into the props
298
- // and ensures that props is always an object
299
- function buildJSXOpeningElementAttributes(attribs, file, children) {
300
- let _props = [];
301
- const objs = [];
302
-
303
- // In order to avoid having duplicate "children" keys, we avoid
304
- // pushing the "children" prop if we have actual children. However,
305
- // the children prop may have side effects, so to be certain
306
- // these side effects are evaluated, we add them to the following prop
307
- // as a sequence expression to preserve order. So:
308
- // <div children={x++} foo={y}>{child}</div> becomes
309
- // React.jsx('div', {foo: (x++, y), children: child});
310
- // duplicateChildren contains the extra children prop values
311
- let duplicateChildren = [];
312
-
313
- const hasChildren = children && children.length > 0;
314
-
315
- const useBuiltIns = file.opts.useBuiltIns || false;
316
- if (typeof useBuiltIns !== 'boolean') {
317
- throw new Error(
318
- 'transform-react-jsx currently only accepts a boolean option for ' +
319
- 'useBuiltIns (defaults to false)',
320
- );
321
- }
322
-
323
- while (attribs.length) {
324
- const prop = attribs.shift();
325
- if (hasChildren && isChildrenProp(prop)) {
326
- duplicateChildren.push(convertAttributeValue(prop.value));
327
- } else if (t.isJSXSpreadAttribute(prop)) {
328
- _props = pushProps(_props, objs);
329
- if (duplicateChildren.length > 0) {
330
- objs.push(
331
- t.sequenceExpression([...duplicateChildren, prop.argument]),
332
- );
333
- duplicateChildren = [];
334
- } else {
335
- objs.push(prop.argument);
336
- }
337
- } else {
338
- _props.push(convertAttribute(prop, duplicateChildren));
339
- if (duplicateChildren.length > 0) {
340
- duplicateChildren = [];
341
- }
342
- }
343
- }
344
-
345
- // In React.JSX, children is no longer a separate argument, but passed in
346
- // through the argument object
347
- if (hasChildren) {
348
- if (children.length === 1) {
349
- _props.push(
350
- t.objectProperty(
351
- t.identifier('children'),
352
- duplicateChildren.length > 0
353
- ? t.sequenceExpression([...duplicateChildren, children[0]])
354
- : children[0],
355
- ),
356
- );
357
- } else {
358
- _props.push(
359
- t.objectProperty(
360
- t.identifier('children'),
361
- duplicateChildren.length > 0
362
- ? t.sequenceExpression([
363
- ...duplicateChildren,
364
- t.arrayExpression(children),
365
- ])
366
- : t.arrayExpression(children),
367
- ),
368
- );
369
- }
370
- }
371
-
372
- pushProps(_props, objs);
373
-
374
- if (objs.length === 1) {
375
- // only one object
376
- if (!t.isObjectExpression(objs[0])) {
377
- // if the prop object isn't an object, use Object.assign or _extends
378
- // to ensure that the prop will always be an object (as opposed to a variable
379
- // that could be null at some point)
380
- const expressionHelper = useBuiltIns
381
- ? t.memberExpression(t.identifier('Object'), t.identifier('assign'))
382
- : file.addHelper('extends');
383
-
384
- attribs = t.callExpression(expressionHelper, [
385
- t.objectExpression([]),
386
- objs[0],
387
- ]);
388
- } else {
389
- attribs = objs[0];
390
- }
391
- } else {
392
- // looks like we have multiple objects
393
- if (!t.isObjectExpression(objs[0])) {
394
- objs.unshift(t.objectExpression([]));
395
- }
396
-
397
- const expressionHelper = useBuiltIns
398
- ? t.memberExpression(t.identifier('Object'), t.identifier('assign'))
399
- : file.addHelper('extends');
400
-
401
- // spread it
402
- attribs = t.callExpression(expressionHelper, objs);
403
- }
404
-
405
- return attribs;
406
- }
407
-
408
- // Builds JSX Fragment <></> into
409
- // Production: React.jsx(type, arguments)
410
- // Development: React.jsxDEV(type, { children})
411
- function buildJSXFragmentCall(path, file) {
412
- if (opts.filter && !opts.filter(path.node, file)) {
413
- return;
414
- }
415
-
416
- const openingPath = path.get('openingElement');
417
- openingPath.parent.children = t.react.buildChildren(openingPath.parent);
418
-
419
- const args = [];
420
- const tagName = null;
421
- const tagExpr = file.get('jsxFragIdentifier')();
422
-
423
- const state = {
424
- tagExpr: tagExpr,
425
- tagName: tagName,
426
- args: args,
427
- };
428
-
429
- if (opts.pre) {
430
- opts.pre(state, file);
431
- }
432
-
433
- let childrenNode;
434
- if (path.node.children.length > 0) {
435
- if (path.node.children.length === 1) {
436
- childrenNode = path.node.children[0];
437
- } else {
438
- childrenNode = t.arrayExpression(path.node.children);
439
- }
440
- }
441
-
442
- args.push(
443
- t.objectExpression(
444
- childrenNode !== undefined
445
- ? [t.objectProperty(t.identifier('children'), childrenNode)]
446
- : [],
447
- ),
448
- );
449
-
450
- if (file.opts.development) {
451
- args.push(
452
- t.identifier('undefined'),
453
- t.booleanLiteral(path.node.children.length > 1),
454
- );
455
- }
456
-
457
- if (opts.post) {
458
- opts.post(state, file);
459
- }
460
-
461
- return (
462
- state.call ||
463
- t.callExpression(
464
- path.node.children.length > 1 ? state.staticCallee : state.callee,
465
- args,
466
- )
467
- );
468
- }
469
-
470
- // Builds JSX into:
471
- // Production: React.createElement(type, arguments, children)
472
- // Development: React.createElement(type, arguments, children, source, self)
473
- function buildCreateElementCall(path, file) {
474
- if (opts.filter && !opts.filter(path.node, file)) {
475
- return;
476
- }
477
-
478
- const openingPath = path.get('openingElement');
479
- openingPath.parent.children = t.react.buildChildren(openingPath.parent);
480
-
481
- const tagExpr = convertJSXIdentifier(
482
- openingPath.node.name,
483
- openingPath.node,
484
- );
485
- const args = [];
486
-
487
- let tagName;
488
- if (t.isIdentifier(tagExpr)) {
489
- tagName = tagExpr.name;
490
- } else if (t.isLiteral(tagExpr)) {
491
- tagName = tagExpr.value;
492
- }
493
-
494
- const state = {
495
- tagExpr: tagExpr,
496
- tagName: tagName,
497
- args: args,
498
- };
499
-
500
- if (opts.pre) {
501
- opts.pre(state, file);
502
- }
503
-
504
- let attribs = openingPath.node.attributes;
505
- if (attribs.length) {
506
- attribs = buildCreateElementOpeningElementAttributes(attribs, file);
507
- } else {
508
- attribs = t.nullLiteral();
509
- }
510
-
511
- args.push(attribs, ...path.node.children);
512
-
513
- if (opts.post) {
514
- opts.post(state, file);
515
- }
516
-
517
- return state.call || t.callExpression(state.oldCallee, args);
518
- }
519
-
520
- function pushProps(_props, objs) {
521
- if (!_props.length) {
522
- return _props;
523
- }
524
-
525
- objs.push(t.objectExpression(_props));
526
- return [];
527
- }
528
-
529
- /**
530
- * The logic for this is quite terse. It's because we need to
531
- * support spread elements. We loop over all attributes,
532
- * breaking on spreads, we then push a new object containing
533
- * all prior attributes to an array for later processing.
534
- */
535
- function buildCreateElementOpeningElementAttributes(attribs, file) {
536
- let _props = [];
537
- const objs = [];
538
-
539
- const useBuiltIns = file.opts.useBuiltIns || false;
540
- if (typeof useBuiltIns !== 'boolean') {
541
- throw new Error(
542
- 'transform-react-jsx currently only accepts a boolean option for ' +
543
- 'useBuiltIns (defaults to false)',
544
- );
545
- }
546
-
547
- while (attribs.length) {
548
- const prop = attribs.shift();
549
- if (t.isJSXSpreadAttribute(prop)) {
550
- _props = pushProps(_props, objs);
551
- objs.push(prop.argument);
552
- } else {
553
- const attr = convertAttribute(prop);
554
- _props.push(attr);
555
- }
556
- }
557
-
558
- pushProps(_props, objs);
559
-
560
- if (objs.length === 1) {
561
- // only one object
562
- attribs = objs[0];
563
- } else {
564
- // looks like we have multiple objects
565
- if (!t.isObjectExpression(objs[0])) {
566
- objs.unshift(t.objectExpression([]));
567
- }
568
-
569
- const expressionHelper = useBuiltIns
570
- ? t.memberExpression(t.identifier('Object'), t.identifier('assign'))
571
- : file.addHelper('extends');
572
-
573
- // spread it
574
- attribs = t.callExpression(expressionHelper, objs);
575
- }
576
-
577
- return attribs;
578
- }
579
-}
580
-
581
-module.exports = function(babel) {
582
- const {types: t} = babel;
583
-
584
- const createIdentifierParser = id => () => {
585
- return id
586
- .split('.')
587
- .map(name => t.identifier(name))
588
- .reduce((object, property) => t.memberExpression(object, property));
589
- };
590
-
591
- const visitor = helper(babel, {
592
- pre(state) {
593
- const tagName = state.tagName;
594
- const args = state.args;
595
- if (t.react.isCompatTag(tagName)) {
596
- args.push(t.stringLiteral(tagName));
597
- } else {
598
- args.push(state.tagExpr);
599
- }
600
- },
601
-
602
- post(state, pass) {
603
- state.callee = pass.get('jsxIdentifier')();
604
- state.staticCallee = pass.get('jsxStaticIdentifier')();
605
- state.oldCallee = pass.get('oldJSXIdentifier')();
606
- },
607
- });
608
-
609
- const createIdentifierName = (path, autoImport, name, importName) => {
610
- if (autoImport === IMPORT_TYPES.none) {
611
- return `React.${name}`;
612
- } else if (autoImport === IMPORT_TYPES.namedExports) {
613
- if (importName) {
614
- const identifierName = `${importName[name]}`;
615
- return identifierName;
616
- }
617
- } else {
618
- return `${importName}.${name}`;
619
- }
620
- };
621
-
622
- function getImportNames(parentPath, state) {
623
- const imports = {};
624
- parentPath.traverse({
625
- JSXElement(path) {
626
- if (shouldUseCreateElement(path, t)) {
627
- imports.createElement = true;
628
- } else if (path.node.children.length > 1) {
629
- const importName = state.development ? 'jsxDEV' : 'jsxs';
630
- imports[importName] = true;
631
- } else {
632
- const importName = state.development ? 'jsxDEV' : 'jsx';
633
- imports[importName] = true;
634
- }
635
- },
636
-
637
- JSXFragment(path) {
638
- imports.Fragment = true;
639
- },
640
- });
641
- return imports;
642
- }
643
-
644
- function hasJSX(parentPath) {
645
- let fileHasJSX = false;
646
- parentPath.traverse({
647
- JSXElement(path) {
648
- fileHasJSX = true;
649
- path.stop();
650
- },
651
-
652
- JSXFragment(path) {
653
- fileHasJSX = true;
654
- path.stop();
655
- },
656
- });
657
-
658
- return fileHasJSX;
659
- }
660
-
661
- function addAutoImports(path, state) {
662
- if (state.autoImport === IMPORT_TYPES.none) {
663
- return;
664
- }
665
-
666
- if (IMPORT_TYPES[state.autoImport] === undefined) {
667
- throw path.buildCodeFrameError(
668
- 'autoImport must be one of the following: ' +
669
- Object.keys(IMPORT_TYPES).join(', '),
670
- );
671
- }
672
- if (state.autoImport === IMPORT_TYPES.require && isModule(path)) {
673
- throw path.buildCodeFrameError(
674
- 'Babel `sourceType` must be set to `script` for autoImport ' +
675
- 'to use `require` syntax. See Babel `sourceType` for details.',
676
- );
677
- }
678
- if (state.autoImport !== IMPORT_TYPES.require && !isModule(path)) {
679
- throw path.buildCodeFrameError(
680
- 'Babel `sourceType` must be set to `module` for autoImport to use `' +
681
- state.autoImport +
682
- '` syntax. See Babel `sourceType` for details.',
683
- );
684
- }
685
-
686
- // import {jsx} from "react";
687
- // import {createElement} from "react";
688
- if (state.autoImport === IMPORT_TYPES.namedExports) {
689
- const imports = getImportNames(path, state);
690
- const importMap = {};
691
-
692
- Object.keys(imports).forEach(importName => {
693
- importMap[importName] = addNamed(path, importName, state.source).name;
694
- });
695
-
696
- return importMap;
697
- }
698
-
699
- // add import to file and get the import name
700
- let name;
701
- if (state.autoImport === IMPORT_TYPES.require) {
702
- // var _react = require("react");
703
- name = addNamespace(path, state.source, {
704
- importedInterop: 'uncompiled',
705
- }).name;
706
- } else if (state.autoImport === IMPORT_TYPES.namespace) {
707
- // import * as _react from "react";
708
- name = addNamespace(path, state.source).name;
709
- } else if (state.autoImport === IMPORT_TYPES.defaultExport) {
710
- // import _default from "react";
711
- name = addDefault(path, state.source).name;
712
- }
713
-
714
- return name;
715
- }
716
-
717
- visitor.Program = {
718
- enter(path, state) {
719
- if (hasJSX(path)) {
720
- let autoImport = state.opts.autoImport || IMPORT_TYPES.none;
721
- let source = state.opts.importSource || 'react';
722
- const {file} = state;
723
-
724
- if (file.ast.comments) {
725
- for (let i = 0; i < file.ast.comments.length; i++) {
726
- const comment = file.ast.comments[i];
727
- const jsxAutoImportMatches = JSX_AUTO_IMPORT_ANNOTATION_REGEX.exec(
728
- comment.value,
729
- );
730
- if (jsxAutoImportMatches) {
731
- autoImport = jsxAutoImportMatches[1];
732
- }
733
- const jsxImportSourceMatches = JSX_IMPORT_SOURCE_ANNOTATION_REGEX.exec(
734
- comment.value,
735
- );
736
- if (jsxImportSourceMatches) {
737
- source = jsxImportSourceMatches[1];
738
- }
739
- }
740
- }
741
-
742
- const importName = addAutoImports(path, {
743
- ...state.opts,
744
- autoImport,
745
- source,
746
- });
747
-
748
- state.set(
749
- 'oldJSXIdentifier',
750
- createIdentifierParser(
751
- createIdentifierName(path, autoImport, 'createElement', importName),
752
- ),
753
- );
754
-
755
- state.set(
756
- 'jsxIdentifier',
757
- createIdentifierParser(
758
- createIdentifierName(
759
- path,
760
- autoImport,
761
- state.opts.development ? 'jsxDEV' : 'jsx',
762
- importName,
763
- ),
764
- ),
765
- );
766
-
767
- state.set(
768
- 'jsxStaticIdentifier',
769
- createIdentifierParser(
770
- createIdentifierName(
771
- path,
772
- autoImport,
773
- state.opts.development ? 'jsxDEV' : 'jsxs',
774
- importName,
775
- ),
776
- ),
777
- );
778
-
779
- state.set(
780
- 'jsxFragIdentifier',
781
- createIdentifierParser(
782
- createIdentifierName(path, autoImport, 'Fragment', importName),
783
- ),
784
- );
785
- }
786
- },
787
- };
788
-
789
- visitor.JSXAttribute = function(path) {
790
- if (t.isJSXElement(path.node.value)) {
791
- path.node.value = t.jsxExpressionContainer(path.node.value);
792
- }
793
- };
794
-
795
- return {
796
- name: 'transform-react-jsx',
797
- visitor,
798
- };
799
-};