@samitouri / QOS-React-2 / commits / a876808f0a

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 &lt; 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 &amp; w</div>;
691 -
692 - <div>w &nbsp; 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 &lt; 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>&nbsp; </div>;`)).toMatchSnapshot();
770 - });
771 -
772 - it('should not strip tags with a single child of nbsp', () => {
773 - expect(transform(`<div>&nbsp;</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 -};