Compare commits
650 Commits
v17.0.1
...
circleci-e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2489f7ce7 | ||
|
|
cae635054e | ||
|
|
e2453e2007 | ||
|
|
73ffce1b6f | ||
|
|
534c9c52ec | ||
|
|
51b0becf3e | ||
|
|
386e8f2ea7 | ||
|
|
7fec38041f | ||
|
|
27c9c95e23 | ||
|
|
8426bb6956 | ||
|
|
e577bfb1ce | ||
|
|
355591add4 | ||
|
|
d7dce572c7 | ||
|
|
06f7b4f43a | ||
|
|
422e0bb360 | ||
|
|
568dc3532e | ||
|
|
43f4cc1608 | ||
|
|
d0f348dc1b | ||
|
|
bd0a963445 | ||
|
|
a0d2d1e1e1 | ||
|
|
6cbf2a8b3b | ||
|
|
c0a77029c4 | ||
|
|
f283d7524a | ||
|
|
03c5314b44 | ||
|
|
7ec4c55971 | ||
|
|
9212d994ba | ||
|
|
9343f87203 | ||
|
|
e601854f07 | ||
|
|
502f8a2a07 | ||
|
|
bd45ad05dc | ||
|
|
a8f5e77b92 | ||
|
|
dbe3363ccd | ||
|
|
101ea9f55c | ||
|
|
1a106bdc2a | ||
|
|
3ba2b67f21 | ||
|
|
905f6f48d4 | ||
|
|
ca4e650ec1 | ||
|
|
42a89d5c61 | ||
|
|
1e3ceadcc0 | ||
|
|
01be61c12f | ||
|
|
cb30388d10 | ||
|
|
c1536795ca | ||
|
|
c96b78e0e7 | ||
|
|
aecb3b6d11 | ||
|
|
1a3f1afbd3 | ||
|
|
e6be2d531d | ||
|
|
6bbe7c3446 | ||
|
|
bc7d5ac99d | ||
|
|
48a11a3efc | ||
|
|
5aa0c5671f | ||
|
|
0eea577248 | ||
|
|
0706162ba7 | ||
|
|
9d17b562ba | ||
|
|
b610fec00c | ||
|
|
23c80959ad | ||
|
|
2568fecc38 | ||
|
|
fccfc24893 | ||
|
|
cc4d24ab0b | ||
|
|
46926993fc | ||
|
|
e0d9b28999 | ||
|
|
1b7b3592f4 | ||
|
|
39f0074892 | ||
|
|
7747a5684d | ||
|
|
8f37942765 | ||
|
|
44cdfd6b7a | ||
|
|
8b4201535c | ||
|
|
2418f24b60 | ||
|
|
154a8cf328 | ||
|
|
6736a38b9a | ||
|
|
86715efa23 | ||
|
|
a8a4742f1c | ||
|
|
1d3558965f | ||
|
|
a8964649bb | ||
|
|
76f85b3e50 | ||
|
|
e16d61c300 | ||
|
|
63091939bd | ||
|
|
efbd69b27e | ||
|
|
8f6163cbed | ||
|
|
28625c6f45 | ||
|
|
d75105fa92 | ||
|
|
3c2341416a | ||
|
|
5151466bab | ||
|
|
0d493dcda9 | ||
|
|
bb1c821556 | ||
|
|
7841d0695a | ||
|
|
6405efc368 | ||
|
|
0ae5290b54 | ||
|
|
965fb8be6b | ||
|
|
2d8d133e17 | ||
|
|
459c34fde6 | ||
|
|
a731a51696 | ||
|
|
51ebccc374 | ||
|
|
97c25b0e9c | ||
|
|
45f1a4a33f | ||
|
|
e0bffeeb01 | ||
|
|
549aaacbb0 | ||
|
|
132b72d7b6 | ||
|
|
b8bbb6a13d | ||
|
|
ebcec3cc20 | ||
|
|
99995c1063 | ||
|
|
3f8f4675d4 | ||
|
|
d6604ac031 | ||
|
|
b15bf2b2f1 | ||
|
|
343776fc90 | ||
|
|
4d402cdda0 | ||
|
|
63927e0843 | ||
|
|
1e3383a411 | ||
|
|
7bef382bf9 | ||
|
|
316943091e | ||
|
|
e0f89aa056 | ||
|
|
1a2d792503 | ||
|
|
9cf1069ffc | ||
|
|
5890e0e692 | ||
|
|
46491dce96 | ||
|
|
b770f75005 | ||
|
|
2bf4805e4b | ||
|
|
b8fda6cabc | ||
|
|
3890fb52fe | ||
|
|
57768ef90b | ||
|
|
e468072e17 | ||
|
|
0a8fefca4c | ||
|
|
6005a6ab2b | ||
|
|
85b543c6b4 | ||
|
|
1bb8987cc9 | ||
|
|
bd070eb2c4 | ||
|
|
46ef1ab32a | ||
|
|
212d2909d3 | ||
|
|
12751d2991 | ||
|
|
8ea11306ad | ||
|
|
014edf1980 | ||
|
|
67ebdf88bf | ||
|
|
e9a4a44aae | ||
|
|
d1542de3a6 | ||
|
|
d19257b8fa | ||
|
|
442eb21e0e | ||
|
|
9a130e1dec | ||
|
|
b522638b99 | ||
|
|
4ca62cac45 | ||
|
|
15fb8c3045 | ||
|
|
aea7c2aab1 | ||
|
|
bacc87068a | ||
|
|
098600c42a | ||
|
|
df420bc0a3 | ||
|
|
ab5b379275 | ||
|
|
fd907c1f15 | ||
|
|
79740da4c6 | ||
|
|
b6644fabb9 | ||
|
|
269dd6ec5d | ||
|
|
3c21aa855a | ||
|
|
9e9dac6505 | ||
|
|
86f3385d9a | ||
|
|
c6702656ff | ||
|
|
1bd41c6645 | ||
|
|
e7e0a90bd8 | ||
|
|
7bac7607a7 | ||
|
|
207d4c3a53 | ||
|
|
2a7bb41548 | ||
|
|
7edd628134 | ||
|
|
a0d6b155dc | ||
|
|
a5267faad5 | ||
|
|
5196a95fd1 | ||
|
|
ecb599cd87 | ||
|
|
8e2bb3e89c | ||
|
|
22ab39be68 | ||
|
|
2182563dc4 | ||
|
|
29faeb2df3 | ||
|
|
4edbcdc327 | ||
|
|
9a2591681e | ||
|
|
4a8deb0836 | ||
|
|
bd4f056a3e | ||
|
|
a2ae42db90 | ||
|
|
fc33f12bde | ||
|
|
7212383945 | ||
|
|
84b9162cbe | ||
|
|
48740429b4 | ||
|
|
0f5ebf366e | ||
|
|
9cd52b27fe | ||
|
|
ad091759a9 | ||
|
|
709f948412 | ||
|
|
af5037a7a8 | ||
|
|
e8cdce40d6 | ||
|
|
a155860018 | ||
|
|
89847bf6e6 | ||
|
|
ef37d55b68 | ||
|
|
a632f7de3b | ||
|
|
bd7f4a013b | ||
|
|
78120032d4 | ||
|
|
a3a7adb83e | ||
|
|
cdb6b4c554 | ||
|
|
7becb2ff1b | ||
|
|
83bdc565f9 | ||
|
|
b9c6a2b30e | ||
|
|
8f202a7c8d | ||
|
|
4def1ceee2 | ||
|
|
af1a4cbf7a | ||
|
|
c3cb2c2b30 | ||
|
|
d14b6a4bdd | ||
|
|
5027eb4650 | ||
|
|
c1a53ad2b2 | ||
|
|
cc4b431dab | ||
|
|
f7cdc89361 | ||
|
|
4c9eb2af1e | ||
|
|
f3337aa544 | ||
|
|
9eddfbf5af | ||
|
|
11b07597ee | ||
|
|
96d00b9bba | ||
|
|
0e100ed00f | ||
|
|
81ef539535 | ||
|
|
266c26ad45 | ||
|
|
a4a940d7a1 | ||
|
|
f4d7a0f1ea | ||
|
|
dde875dfb1 | ||
|
|
a597c2f5dc | ||
|
|
68097787f6 | ||
|
|
15e779d921 | ||
|
|
4f76a28c93 | ||
|
|
6b3d86a2e9 | ||
|
|
82ef450e0e | ||
|
|
ea155e2267 | ||
|
|
dbadfa2c36 | ||
|
|
84c06fef81 | ||
|
|
686b635b71 | ||
|
|
dd8552ae0d | ||
|
|
9d48779b36 | ||
|
|
bb88ce95a8 | ||
|
|
343710c923 | ||
|
|
933880b454 | ||
|
|
b0407b55ff | ||
|
|
39713716aa | ||
|
|
d4cae99f2a | ||
|
|
8a4a59c725 | ||
|
|
bdc23c3dba | ||
|
|
dc108b0f55 | ||
|
|
6ea749170b | ||
|
|
b38ac13f94 | ||
|
|
b943aeba88 | ||
|
|
d389c54d17 | ||
|
|
c486dc1a46 | ||
|
|
cf45a623a1 | ||
|
|
75c616554d | ||
|
|
1214b302e1 | ||
|
|
1a02d2792e | ||
|
|
782f689ca8 | ||
|
|
e90c76a651 | ||
|
|
1f8583de8c | ||
|
|
ad6e6ec7bb | ||
|
|
172e89b4bf | ||
|
|
ee6a05c2bf | ||
|
|
d778518998 | ||
|
|
7c1ba2b57d | ||
|
|
316aa36865 | ||
|
|
a817840ea7 | ||
|
|
b4f119cdf1 | ||
|
|
c03197063d | ||
|
|
94fd1214d2 | ||
|
|
b130a0f5cd | ||
|
|
2c9fef32db | ||
|
|
1cf9978d89 | ||
|
|
a423a01223 | ||
|
|
588db2e1fc | ||
|
|
9ed0167945 | ||
|
|
b9e4c10e99 | ||
|
|
0e96bdd4ee | ||
|
|
f8ef4ff571 | ||
|
|
b48b38af68 | ||
|
|
c9aab1c9d0 | ||
|
|
516b76b9ae | ||
|
|
0853aab74d | ||
|
|
d1294c9d40 | ||
|
|
e40f0b2603 | ||
|
|
cecfde51b6 | ||
|
|
8e76371241 | ||
|
|
64983aab5d | ||
|
|
634cc52e61 | ||
|
|
1102224bbb | ||
|
|
dbe98a5aae | ||
|
|
3ba5c87377 | ||
|
|
46b68eaf62 | ||
|
|
dcd13045ef | ||
|
|
5f21a9fca4 | ||
|
|
32d6f39edd | ||
|
|
a5aa9d5253 | ||
|
|
a77dd13ede | ||
|
|
048ee4c0cd | ||
|
|
556644e237 | ||
|
|
8b741437b1 | ||
|
|
38a1aedb49 | ||
|
|
1b7e471b91 | ||
|
|
a7c57268fb | ||
|
|
4a99c5c3a7 | ||
|
|
77be527297 | ||
|
|
3221e8fba4 | ||
|
|
05ec0d7646 | ||
|
|
03ede83d2e | ||
|
|
6a589ad711 | ||
|
|
148f8e497c | ||
|
|
a63f0953be | ||
|
|
fb8c1917e9 | ||
|
|
fa868d6be7 | ||
|
|
eb58c3909a | ||
|
|
7b84dbd169 | ||
|
|
2c9d8efc8e | ||
|
|
d0eaf78293 | ||
|
|
435cff9866 | ||
|
|
25bfa287f6 | ||
|
|
7c4e6aae3e | ||
|
|
8fe7810e70 | ||
|
|
cc1a46dfd2 | ||
|
|
a5c3baeecd | ||
|
|
6c3202b1e1 | ||
|
|
dcdf8de7e1 | ||
|
|
ca99ae97b4 | ||
|
|
1fafac0028 | ||
|
|
6d3ecb70dc | ||
|
|
754e307284 | ||
|
|
be5a2e231a | ||
|
|
f6bc9c8243 | ||
|
|
7d06b80af6 | ||
|
|
154b85213a | ||
|
|
cf485e6f6b | ||
|
|
3fb11eed9a | ||
|
|
119736b1c2 | ||
|
|
bf11788bf0 | ||
|
|
825c3021f0 | ||
|
|
1d1e49cfa4 | ||
|
|
533aed8de6 | ||
|
|
466b26c926 | ||
|
|
89acfa639b | ||
|
|
0203b6567c | ||
|
|
c9f6d0a3a8 | ||
|
|
f8979e0e28 | ||
|
|
b9c4a01f71 | ||
|
|
00d4f95c2a | ||
|
|
c06d245fc7 | ||
|
|
f227e7f26b | ||
|
|
14e4fd1ff2 | ||
|
|
f2b6bf7c86 | ||
|
|
10cc400184 | ||
|
|
bd245c1bab | ||
|
|
b7e6310669 | ||
|
|
860f673a7a | ||
|
|
acde654698 | ||
|
|
6556e2a874 | ||
|
|
60182d64ca | ||
|
|
ec372faefe | ||
|
|
e4d4b7074d | ||
|
|
5d1d1679bf | ||
|
|
73e900b0e7 | ||
|
|
a3f30fed29 | ||
|
|
41e62e7719 | ||
|
|
431e76e2db | ||
|
|
e89d74ee67 | ||
|
|
5fe091c778 | ||
|
|
ca15606d81 | ||
|
|
e7d2a558ad | ||
|
|
cb88572227 | ||
|
|
d74559746c | ||
|
|
f04bcb8139 | ||
|
|
c7b4497988 | ||
|
|
258b375a41 | ||
|
|
7df65725ba | ||
|
|
ee43263572 | ||
|
|
de0ee76dbd | ||
|
|
d857f9e4d0 | ||
|
|
553440bd15 | ||
|
|
38f392ceda | ||
|
|
0cf9fc10ba | ||
|
|
2e8bbcb54e | ||
|
|
c581cdd480 | ||
|
|
90bde6505e | ||
|
|
8336f19aa8 | ||
|
|
9209c30ff9 | ||
|
|
4190a34588 | ||
|
|
e5f6b91d29 | ||
|
|
c62986cfd8 | ||
|
|
78d2f2d301 | ||
|
|
cfd8c1bd43 | ||
|
|
4d28eca97e | ||
|
|
8af27aeedb | ||
|
|
af3d52611d | ||
|
|
8fa0ccca00 | ||
|
|
0991647921 | ||
|
|
e2fd460cca | ||
|
|
9e8f3c8955 | ||
|
|
6f8843837c | ||
|
|
1a74726246 | ||
|
|
696e736be1 | ||
|
|
483358c38f | ||
|
|
78ec97d34a | ||
|
|
4c5275fec7 | ||
|
|
67e8419823 | ||
|
|
6cdc35972d | ||
|
|
47dd9f4413 | ||
|
|
114ab52953 | ||
|
|
d3d2451a08 | ||
|
|
b593a6f778 | ||
|
|
9e9be6c6b3 | ||
|
|
eee874ce6e | ||
|
|
3b870b1e09 | ||
|
|
d1845ad0ff | ||
|
|
3499c343ab | ||
|
|
3d10eca241 | ||
|
|
ad8211d96a | ||
|
|
d919e2c41c | ||
|
|
97fce318a6 | ||
|
|
6c526c5153 | ||
|
|
35f7441d37 | ||
|
|
b4658f2daa | ||
|
|
a014c915c7 | ||
|
|
77754ae618 | ||
|
|
b5bac18219 | ||
|
|
bbb2ba8c8d | ||
|
|
903384ab0c | ||
|
|
4ecf11977c | ||
|
|
eeb1325b03 | ||
|
|
4e08fb10c9 | ||
|
|
b12d0078a4 | ||
|
|
a703c3f7e8 | ||
|
|
365080f4f5 | ||
|
|
f58ad2ad8e | ||
|
|
c64d6d21be | ||
|
|
4c019585e8 | ||
|
|
3b02ae5cc6 | ||
|
|
c1cfa734fd | ||
|
|
00e38c80b2 | ||
|
|
3be750eee9 | ||
|
|
85f489a129 | ||
|
|
0935a1db3d | ||
|
|
b936ab660a | ||
|
|
2d025753e2 | ||
|
|
0e526bcec2 | ||
|
|
7e36d8beba | ||
|
|
c47f3cfa17 | ||
|
|
3e0bdbefa3 | ||
|
|
7cb9fd7ef8 | ||
|
|
dc27b5aaae | ||
|
|
f8545f6eb8 | ||
|
|
f8b6969da6 | ||
|
|
bb1b7951d1 | ||
|
|
766a7a28a9 | ||
|
|
a922f1c710 | ||
|
|
e51bd6c1fa | ||
|
|
aa736a0fa6 | ||
|
|
deeeaf1d22 | ||
|
|
e316f78552 | ||
|
|
9c32622cf0 | ||
|
|
d13f5b9538 | ||
|
|
db5945efee | ||
|
|
a511dc7090 | ||
|
|
fb3f63f1ab | ||
|
|
6d94017c42 | ||
|
|
f0031dc6ed | ||
|
|
895ae67fd3 | ||
|
|
f15f8f64bb | ||
|
|
0fd6805c6d | ||
|
|
a6b5256a29 | ||
|
|
3957853ae5 | ||
|
|
d4c05a1ead | ||
|
|
fceb75e899 | ||
|
|
741dcbdbec | ||
|
|
11a983fc76 | ||
|
|
2e948e0d91 | ||
|
|
2a646f73e4 | ||
|
|
fb3e158a64 | ||
|
|
e0fd9e67fc | ||
|
|
58e8304483 | ||
|
|
9043626f09 | ||
|
|
af0bb68e87 | ||
|
|
2b6985114f | ||
|
|
ba9582da27 | ||
|
|
af16f755dc | ||
|
|
9a2150719b | ||
|
|
95feb0e701 | ||
|
|
6132919bf2 | ||
|
|
98313aaa7e | ||
|
|
42e04b46d1 | ||
|
|
a656ace8da | ||
|
|
fc07b070a0 | ||
|
|
e6ed2bcf42 | ||
|
|
b99ac3d6df | ||
|
|
9a6a41d108 | ||
|
|
eb0fb38230 | ||
|
|
e8eff119e0 | ||
|
|
27659559eb | ||
|
|
beb38aba3e | ||
|
|
6630c2de2a | ||
|
|
50393dc3a0 | ||
|
|
09a2c363a5 | ||
|
|
6cbb9394d1 | ||
|
|
99554dc36f | ||
|
|
1bda600378 | ||
|
|
efc57e5cbb | ||
|
|
00a5b08e24 | ||
|
|
a6329b1050 | ||
|
|
1cf59f34b8 | ||
|
|
ab29695a05 | ||
|
|
d37d7a4bb4 | ||
|
|
19e15a3986 | ||
|
|
ff17fc176f | ||
|
|
5687864eb7 | ||
|
|
9f338e5d77 | ||
|
|
4e62fd2712 | ||
|
|
604bbcd87d | ||
|
|
070372cde2 | ||
|
|
0f80dd1484 | ||
|
|
daf38ecdfc | ||
|
|
3f9205c333 | ||
|
|
cdfde3ae11 | ||
|
|
b15d6e93e7 | ||
|
|
40ff2395e4 | ||
|
|
94aa365e3a | ||
|
|
842ee367e6 | ||
|
|
dbf40ef759 | ||
|
|
03126dd087 | ||
|
|
b51a686a93 | ||
|
|
56a632adb6 | ||
|
|
1a24223375 | ||
|
|
a233c9e2aa | ||
|
|
6a4b12b81c | ||
|
|
7659949d65 | ||
|
|
b9680aef7d | ||
|
|
cdae31ab8e | ||
|
|
51a7cfe210 | ||
|
|
373b297c55 | ||
|
|
1b5ca99063 | ||
|
|
5fd9db732d | ||
|
|
ce40f1dc2f | ||
|
|
0512cd6a26 | ||
|
|
b66ae09b6e | ||
|
|
de75315d7e | ||
|
|
1377e465dd | ||
|
|
18d7574ae2 | ||
|
|
30dfb86025 | ||
|
|
dd16b78990 | ||
|
|
4053c76b7d | ||
|
|
0db61a08be | ||
|
|
3a8c04e3b2 | ||
|
|
f160547f47 | ||
|
|
9b8060041b | ||
|
|
60e4a76fa8 | ||
|
|
88ef95712d | ||
|
|
e9860d426f | ||
|
|
41c5d00fc9 | ||
|
|
e23673b511 | ||
|
|
555eeae33d | ||
|
|
148ffe3cfe | ||
|
|
ad6f3d5c55 | ||
|
|
a2a025537d | ||
|
|
5711811da1 | ||
|
|
3f73dcee37 | ||
|
|
565148d751 | ||
|
|
e6a0f27630 | ||
|
|
2cf8f7f61c | ||
|
|
d93b58a5e3 | ||
|
|
89d4fe141a | ||
|
|
a81c02ac15 | ||
|
|
ac2cff4b10 | ||
|
|
0f83a64eda | ||
|
|
ebf158965f | ||
|
|
82e99e1b02 | ||
|
|
bf7b7aeb10 | ||
|
|
369c3db629 | ||
|
|
765e89b908 | ||
|
|
7548dd573e | ||
|
|
bd8bc5afce | ||
|
|
453df3ff72 | ||
|
|
73bf2d68ef | ||
|
|
b44e4b13a9 | ||
|
|
3ebf05183d | ||
|
|
2fbcc98066 | ||
|
|
504222dcd2 | ||
|
|
1b96ee444e | ||
|
|
e41fd1fc06 | ||
|
|
760d9ab57a | ||
|
|
9403c3b536 | ||
|
|
11a2ae3a0d | ||
|
|
62efd9618b | ||
|
|
e7006d67df | ||
|
|
15df051c94 | ||
|
|
9aca239f11 | ||
|
|
12627f93b5 | ||
|
|
163199d8cc | ||
|
|
76a6dbcb9a | ||
|
|
35e53b4653 | ||
|
|
16e6dadba6 | ||
|
|
e855f91e85 | ||
|
|
c896cf9617 | ||
|
|
0898660154 | ||
|
|
393c452e39 | ||
|
|
93c3dc54b6 | ||
|
|
13a62feab8 | ||
|
|
7a73d6a0f9 | ||
|
|
fc06cf8d35 | ||
|
|
c29710a570 | ||
|
|
6b28eb6175 | ||
|
|
31d096605c | ||
|
|
2af07d3f4d | ||
|
|
c3e20f18fe | ||
|
|
454c2211c0 | ||
|
|
56e9feead0 | ||
|
|
3fbd47b862 | ||
|
|
930ce7c15a | ||
|
|
39eb6d1765 | ||
|
|
ffd8423356 | ||
|
|
343d7a4a7e | ||
|
|
b6a750be3c | ||
|
|
779a472b09 | ||
|
|
25b18d31c8 | ||
|
|
06a4615be2 | ||
|
|
4e5d7faf54 | ||
|
|
3314115cb4 | ||
|
|
eaaf4cbce7 | ||
|
|
928a819a28 | ||
|
|
6f62abb58a | ||
|
|
40cfe1f486 | ||
|
|
a50f638b06 | ||
|
|
f021a983aa | ||
|
|
46ed268471 | ||
|
|
d1bb4d851f | ||
|
|
c59c3dfe55 | ||
|
|
75726fadfd | ||
|
|
51a3aa6afb | ||
|
|
7b6cac9522 | ||
|
|
dfb6a40335 | ||
|
|
37cb732c59 | ||
|
|
eb3181e772 | ||
|
|
0dd809bdfa | ||
|
|
e9f5ad2584 | ||
|
|
b093528650 | ||
|
|
f668b6c351 | ||
|
|
8df7b7911a | ||
|
|
2eb3181eb4 | ||
|
|
c57fe4a2c1 | ||
|
|
02da938fd5 | ||
|
|
d95c4938df | ||
|
|
b5eabd543f | ||
|
|
020d3aa4e8 | ||
|
|
4eb589169c | ||
|
|
6d50a9d090 | ||
|
|
f75f8b48a2 | ||
|
|
880587366d | ||
|
|
e614e69657 | ||
|
|
7559722a86 | ||
|
|
7e405d458d | ||
|
|
4890779729 | ||
|
|
f46a80ae11 | ||
|
|
0a4c7c5651 | ||
|
|
993ca533b4 | ||
|
|
40c52de960 | ||
|
|
6eca8eff08 |
@@ -1,4 +1,4 @@
|
||||
version: 2
|
||||
version: 2.1
|
||||
|
||||
aliases:
|
||||
- &docker
|
||||
@@ -16,42 +16,28 @@ aliases:
|
||||
restore_cache:
|
||||
name: Restore node_modules cache
|
||||
keys:
|
||||
- v2-node-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }}-node-modules
|
||||
- v2-node-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }}-{{ checksum "workspace_info.txt" }}-node-modules
|
||||
|
||||
- &TEST_PARALLELISM 20
|
||||
|
||||
- &attach_workspace
|
||||
at: build
|
||||
|
||||
- &process_artifacts
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace: *attach_workspace
|
||||
- *restore_node_modules
|
||||
- run: node ./scripts/rollup/consolidateBundleSizes.js
|
||||
- run: ./scripts/circleci/pack_and_store_artifact.sh
|
||||
- store_artifacts:
|
||||
path: ./node_modules.tgz
|
||||
- store_artifacts:
|
||||
path: ./build.tgz
|
||||
- store_artifacts:
|
||||
path: ./build/bundle-sizes.json
|
||||
- store_artifacts:
|
||||
# TODO: Update release script to use local file instead of pulling
|
||||
# from artifacts.
|
||||
path: ./scripts/error-codes/codes.json
|
||||
- persist_to_workspace:
|
||||
root: build
|
||||
paths:
|
||||
- bundle-sizes.json
|
||||
# The CircleCI API doesn't yet support triggering a specific workflow, but it
|
||||
# does support triggering a pipeline. So as a workaround you can triggger the
|
||||
# entire pipeline and use parameters to disable everything except the workflow
|
||||
# you want. CircleCI recommends this workaround here:
|
||||
# https://support.circleci.com/hc/en-us/articles/360050351292-How-to-trigger-a-workflow-via-CircleCI-API-v2-
|
||||
parameters:
|
||||
# This is only set when triggering the CI pipeline via an API request.
|
||||
prerelease_commit_sha:
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
jobs:
|
||||
setup:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
@@ -61,6 +47,7 @@ jobs:
|
||||
- run:
|
||||
name: Install Packages
|
||||
command: yarn --frozen-lockfile --cache-folder ~/.cache/yarn
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- save_cache:
|
||||
# Store the yarn cache globally for all lock files with this same
|
||||
# checksum. This will speed up the setup job for all PRs where the
|
||||
@@ -75,7 +62,7 @@ jobs:
|
||||
# all jobs run on this branch with the same lockfile.
|
||||
name: Save node_modules cache
|
||||
# This cache key is per branch, a yarn install in setup is required.
|
||||
key: v2-node-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }}-node-modules
|
||||
key: v2-node-{{ arch }}-{{ .Branch }}-{{ checksum "yarn.lock" }}-{{ checksum "workspace_info.txt" }}-node-modules
|
||||
paths:
|
||||
- node_modules
|
||||
|
||||
@@ -85,6 +72,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run: node ./scripts/prettier/index
|
||||
- run: node ./scripts/tasks/eslint
|
||||
@@ -95,138 +83,21 @@ jobs:
|
||||
yarn_flow:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: 5
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run: node ./scripts/tasks/flow-ci
|
||||
|
||||
RELEASE_CHANNEL_stable_yarn_test:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=stable --ci
|
||||
|
||||
yarn_test:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
steps:
|
||||
- checkout
|
||||
- *restore_node_modules
|
||||
- run: yarn test --ci
|
||||
|
||||
RELEASE_CHANNEL_stable_yarn_test_www:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
steps:
|
||||
- checkout
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=www-classic --ci
|
||||
|
||||
RELEASE_CHANNEL_stable_yarn_test_www_variant:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
steps:
|
||||
- checkout
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=www-classic --variant --ci
|
||||
|
||||
RELEASE_CHANNEL_stable_yarn_test_prod_www:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
steps:
|
||||
- checkout
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=www-classic --prod --ci
|
||||
|
||||
RELEASE_CHANNEL_stable_yarn_test_prod_www_variant:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
steps:
|
||||
- checkout
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=www-classic --prod --variant --ci
|
||||
|
||||
yarn_test_www:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
steps:
|
||||
- checkout
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=www-modern --ci
|
||||
|
||||
yarn_test_www_variant:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
steps:
|
||||
- checkout
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=www-modern --variant --ci
|
||||
|
||||
yarn_test_prod_www:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
steps:
|
||||
- checkout
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=www-modern --prod --ci
|
||||
|
||||
yarn_test_prod_www_variant:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
steps:
|
||||
- checkout
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=www-modern --prod --variant --ci
|
||||
|
||||
RELEASE_CHANNEL_stable_yarn_test_persistent:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=stable --persistent --ci
|
||||
|
||||
RELEASE_CHANNEL_stable_yarn_test_prod:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
|
||||
steps:
|
||||
- checkout
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=stable --prod --ci
|
||||
|
||||
yarn_test_prod:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
steps:
|
||||
- checkout
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=experimental --prod --ci
|
||||
|
||||
RELEASE_CHANNEL_stable_yarn_build:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
steps:
|
||||
- checkout
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run:
|
||||
environment:
|
||||
@@ -242,6 +113,7 @@ jobs:
|
||||
- RELEASE_CHANNEL
|
||||
- facebook-www
|
||||
- facebook-react-native
|
||||
- facebook-relay
|
||||
- node_modules
|
||||
- react-native
|
||||
- dist
|
||||
@@ -253,6 +125,7 @@ jobs:
|
||||
parallelism: 20
|
||||
steps:
|
||||
- checkout
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run:
|
||||
environment:
|
||||
@@ -268,17 +141,80 @@ jobs:
|
||||
- RELEASE_CHANNEL
|
||||
- facebook-www
|
||||
- facebook-react-native
|
||||
- facebook-relay
|
||||
- node_modules
|
||||
- react-native
|
||||
- dist
|
||||
- sizes/*.json
|
||||
|
||||
yarn_build_combined:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: 40
|
||||
steps:
|
||||
- checkout
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run: yarn build-combined
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- build2
|
||||
|
||||
get_base_build:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
steps:
|
||||
- checkout
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run:
|
||||
name: Download artifacts for base revision
|
||||
command: |
|
||||
git fetch origin main
|
||||
cd ./scripts/release && yarn && cd ../../
|
||||
scripts/release/download-experimental-build.js --commit=$(git merge-base HEAD origin/main)
|
||||
mv ./build2 ./base-build
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- base-build
|
||||
|
||||
process_artifacts_combined:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run: echo "<< pipeline.git.revision >>" >> build2/COMMIT_SHA
|
||||
# Compress build directory into a single tarball for easy download
|
||||
- run: tar -zcvf ./build2.tgz ./build2
|
||||
- store_artifacts:
|
||||
path: ./build2.tgz
|
||||
|
||||
sizebot:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run: echo "<< pipeline.git.revision >>" >> build2/COMMIT_SHA
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run:
|
||||
command: node ./scripts/tasks/danger
|
||||
|
||||
build_devtools_and_process_artifacts:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace: *attach_workspace
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_yarn_cache
|
||||
- *restore_node_modules
|
||||
- run:
|
||||
@@ -297,6 +233,7 @@ jobs:
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace: *attach_workspace
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_yarn_cache
|
||||
- *restore_node_modules
|
||||
- run:
|
||||
@@ -316,7 +253,7 @@ jobs:
|
||||
root: packages/react-devtools-scheduling-profiler
|
||||
paths:
|
||||
- dist
|
||||
|
||||
|
||||
deploy_devtools_scheduling_profiler:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
@@ -324,6 +261,7 @@ jobs:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: packages/react-devtools-scheduling-profiler
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run:
|
||||
name: Deploy
|
||||
@@ -331,92 +269,44 @@ jobs:
|
||||
cd packages/react-devtools-scheduling-profiler
|
||||
yarn vercel deploy dist --prod --confirm --token $SCHEDULING_PROFILER_DEPLOY_VERCEL_TOKEN
|
||||
|
||||
# These jobs are named differently so we can distinguish the stable and
|
||||
# and experimental artifacts
|
||||
process_artifacts: *process_artifacts
|
||||
process_artifacts_experimental: *process_artifacts
|
||||
|
||||
sizebot_stable:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace: *attach_workspace
|
||||
- *restore_node_modules
|
||||
# This runs in the process_artifacts job, too, but it's faster to run
|
||||
# this step in both jobs instead of running the jobs sequentially
|
||||
- run: node ./scripts/rollup/consolidateBundleSizes.js
|
||||
- run:
|
||||
environment:
|
||||
RELEASE_CHANNEL: stable
|
||||
command: node ./scripts/tasks/danger
|
||||
|
||||
sizebot_experimental:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace: *attach_workspace
|
||||
- *restore_node_modules
|
||||
# This runs in the process_artifacts job, too, but it's faster to run
|
||||
# this step in both jobs instead of running the jobs sequentially
|
||||
- run: node ./scripts/rollup/consolidateBundleSizes.js
|
||||
- run:
|
||||
environment:
|
||||
RELEASE_CHANNEL: experimental
|
||||
command: node ./scripts/tasks/danger
|
||||
|
||||
yarn_lint_build:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace: *attach_workspace
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run: yarn lint-build
|
||||
- run: scripts/circleci/check_minified_errors.sh
|
||||
|
||||
RELEASE_CHANNEL_stable_yarn_lint_build:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace: *attach_workspace
|
||||
- *restore_node_modules
|
||||
- run:
|
||||
environment:
|
||||
RELEASE_CHANNEL: stable
|
||||
command: yarn lint-build
|
||||
- run: scripts/circleci/check_minified_errors.sh
|
||||
|
||||
RELEASE_CHANNEL_stable_yarn_test_build:
|
||||
yarn_test:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
parameters:
|
||||
args:
|
||||
type: string
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace: *attach_workspace
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=stable --build --ci
|
||||
- run: yarn test <<parameters.args>> --ci
|
||||
|
||||
yarn_test_build:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
parameters:
|
||||
args:
|
||||
type: string
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace: *attach_workspace
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=experimental --build --ci
|
||||
|
||||
yarn_test_build_devtools:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace: *attach_workspace
|
||||
- *restore_node_modules
|
||||
- run: yarn test --project=devtools --build --ci
|
||||
- run: yarn test --build <<parameters.args>> --ci
|
||||
|
||||
RELEASE_CHANNEL_stable_yarn_test_dom_fixtures:
|
||||
docker: *docker
|
||||
@@ -424,6 +314,7 @@ jobs:
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace: *attach_workspace
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run:
|
||||
name: Run DOM fixture tests
|
||||
@@ -440,6 +331,7 @@ jobs:
|
||||
environment: *environment
|
||||
steps:
|
||||
- checkout
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run:
|
||||
name: Run fuzz tests
|
||||
@@ -447,122 +339,69 @@ jobs:
|
||||
FUZZ_TEST_SEED=$RANDOM yarn test fuzz --ci
|
||||
FUZZ_TEST_SEED=$RANDOM yarn test --prod fuzz --ci
|
||||
|
||||
RELEASE_CHANNEL_stable_yarn_test_build_prod:
|
||||
publish_prerelease:
|
||||
parameters:
|
||||
commit_sha:
|
||||
type: string
|
||||
release_channel:
|
||||
type: string
|
||||
dist_tag:
|
||||
type: string
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace: *attach_workspace
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=stable --build --prod --ci
|
||||
- run:
|
||||
name: Run publish script
|
||||
command: |
|
||||
git fetch origin main
|
||||
cd ./scripts/release && yarn && cd ../../
|
||||
scripts/release/prepare-release-from-ci.js --skipTests -r << parameters.release_channel >> --commit=<< parameters.commit_sha >>
|
||||
cp ./scripts/release/ci-npmrc ~/.npmrc
|
||||
scripts/release/publish.js --ci --tags << parameters.dist_tag >>
|
||||
|
||||
yarn_test_build_prod:
|
||||
# We don't always keep the reconciler forks in sync (otherwise it we wouldn't
|
||||
# have forked it) but during periods when they are meant to be in sync, we
|
||||
# use this job to confirm there are no differences.
|
||||
sync_reconciler_forks:
|
||||
docker: *docker
|
||||
environment: *environment
|
||||
parallelism: *TEST_PARALLELISM
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace: *attach_workspace
|
||||
- run: yarn workspaces info | head -n -1 > workspace_info.txt
|
||||
- *restore_node_modules
|
||||
- run: yarn test --release-channel=experimental --build --prod --ci
|
||||
- run:
|
||||
name: Confirm reconciler forks are the same
|
||||
command: |
|
||||
yarn replace-fork
|
||||
git diff --quiet || (echo "Reconciler forks are not the same! Run yarn replace-fork. Or, if this was intentional, disable this CI check." && false)
|
||||
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
stable:
|
||||
unless: << pipeline.parameters.prerelease_commit_sha >>
|
||||
jobs:
|
||||
- setup
|
||||
- yarn_lint:
|
||||
requires:
|
||||
- setup
|
||||
- yarn_flow:
|
||||
requires:
|
||||
- setup
|
||||
- RELEASE_CHANNEL_stable_yarn_test:
|
||||
requires:
|
||||
- setup
|
||||
- RELEASE_CHANNEL_stable_yarn_test_prod:
|
||||
requires:
|
||||
- setup
|
||||
- RELEASE_CHANNEL_stable_yarn_test_persistent:
|
||||
requires:
|
||||
- setup
|
||||
- RELEASE_CHANNEL_stable_yarn_test_www:
|
||||
requires:
|
||||
- setup
|
||||
- RELEASE_CHANNEL_stable_yarn_test_www_variant:
|
||||
requires:
|
||||
- setup
|
||||
- RELEASE_CHANNEL_stable_yarn_test_prod_www:
|
||||
requires:
|
||||
- setup
|
||||
- RELEASE_CHANNEL_stable_yarn_test_prod_www_variant:
|
||||
requires:
|
||||
- setup
|
||||
- RELEASE_CHANNEL_stable_yarn_build:
|
||||
requires:
|
||||
- setup
|
||||
- process_artifacts:
|
||||
requires:
|
||||
- RELEASE_CHANNEL_stable_yarn_build
|
||||
- sizebot_stable:
|
||||
requires:
|
||||
- RELEASE_CHANNEL_stable_yarn_build
|
||||
- RELEASE_CHANNEL_stable_yarn_lint_build:
|
||||
requires:
|
||||
- RELEASE_CHANNEL_stable_yarn_build
|
||||
- RELEASE_CHANNEL_stable_yarn_test_build:
|
||||
requires:
|
||||
- RELEASE_CHANNEL_stable_yarn_build
|
||||
- RELEASE_CHANNEL_stable_yarn_test_build_prod:
|
||||
requires:
|
||||
- RELEASE_CHANNEL_stable_yarn_build
|
||||
- RELEASE_CHANNEL_stable_yarn_test_dom_fixtures:
|
||||
requires:
|
||||
- RELEASE_CHANNEL_stable_yarn_build
|
||||
|
||||
experimental:
|
||||
unless: << pipeline.parameters.prerelease_commit_sha >>
|
||||
jobs:
|
||||
- setup
|
||||
- yarn_test:
|
||||
requires:
|
||||
- setup
|
||||
- yarn_test_prod:
|
||||
requires:
|
||||
- setup
|
||||
- yarn_test_www:
|
||||
requires:
|
||||
- setup
|
||||
- yarn_test_www_variant:
|
||||
requires:
|
||||
- setup
|
||||
- yarn_test_prod_www:
|
||||
requires:
|
||||
- setup
|
||||
- yarn_test_prod_www_variant:
|
||||
requires:
|
||||
- setup
|
||||
- yarn_build:
|
||||
requires:
|
||||
- setup
|
||||
- process_artifacts_experimental:
|
||||
requires:
|
||||
- yarn_build
|
||||
- sizebot_experimental:
|
||||
requires:
|
||||
- yarn_build
|
||||
- yarn_test_build:
|
||||
requires:
|
||||
- yarn_build
|
||||
- yarn_test_build_prod:
|
||||
requires:
|
||||
- yarn_build
|
||||
- yarn_lint_build:
|
||||
requires:
|
||||
- yarn_build
|
||||
- yarn_test_build_devtools:
|
||||
requires:
|
||||
- yarn_build
|
||||
- build_devtools_and_process_artifacts:
|
||||
requires:
|
||||
- yarn_build
|
||||
@@ -575,9 +414,99 @@ workflows:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- main
|
||||
|
||||
# New workflow that will replace "stable" and "experimental"
|
||||
build_and_test:
|
||||
unless: << pipeline.parameters.prerelease_commit_sha >>
|
||||
jobs:
|
||||
- setup
|
||||
- yarn_flow:
|
||||
requires:
|
||||
- setup
|
||||
# NOTE: This job is only enabled when we want the forks to be in sync.
|
||||
# When the forks intentionally diverge, comment out the job to disable it.
|
||||
- sync_reconciler_forks:
|
||||
requires:
|
||||
- setup
|
||||
- yarn_test:
|
||||
requires:
|
||||
- setup
|
||||
matrix:
|
||||
parameters:
|
||||
args:
|
||||
# Intentionally passing these as strings instead of creating a
|
||||
# separate parameter per CLI argument, since it's easier to
|
||||
# control/see which combinations we want to run.
|
||||
- "-r=stable --env=development"
|
||||
- "-r=stable --env=production"
|
||||
- "-r=experimental --env=development"
|
||||
- "-r=experimental --env=production"
|
||||
- "-r=www-classic --env=development --variant=false"
|
||||
- "-r=www-classic --env=production --variant=false"
|
||||
- "-r=www-classic --env=development --variant=true"
|
||||
- "-r=www-classic --env=production --variant=true"
|
||||
- "-r=www-modern --env=development --variant=false"
|
||||
- "-r=www-modern --env=production --variant=false"
|
||||
- "-r=www-modern --env=development --variant=true"
|
||||
- "-r=www-modern --env=production --variant=true"
|
||||
|
||||
# TODO: Test more persistent configurations?
|
||||
- '-r=stable --env=development --persistent'
|
||||
- yarn_build_combined:
|
||||
requires:
|
||||
- setup
|
||||
- process_artifacts_combined:
|
||||
requires:
|
||||
- yarn_build_combined
|
||||
- yarn_test_build:
|
||||
requires:
|
||||
- yarn_build_combined
|
||||
matrix:
|
||||
parameters:
|
||||
args:
|
||||
# Intentionally passing these as strings instead of creating a
|
||||
# separate parameter per CLI argument, since it's easier to
|
||||
# control/see which combinations we want to run.
|
||||
- "-r=stable --env=development"
|
||||
- "-r=stable --env=production"
|
||||
- "-r=experimental --env=development"
|
||||
- "-r=experimental --env=production"
|
||||
|
||||
# Dev Tools
|
||||
- "--project=devtools -r=experimental"
|
||||
|
||||
# TODO: Update test config to support www build tests
|
||||
# - "-r=www-classic --env=development --variant=false"
|
||||
# - "-r=www-classic --env=production --variant=false"
|
||||
# - "-r=www-classic --env=development --variant=true"
|
||||
# - "-r=www-classic --env=production --variant=true"
|
||||
# - "-r=www-modern --env=development --variant=false"
|
||||
# - "-r=www-modern --env=production --variant=false"
|
||||
# - "-r=www-modern --env=development --variant=true"
|
||||
# - "-r=www-modern --env=production --variant=true"
|
||||
|
||||
# TODO: Test more persistent configurations?
|
||||
- get_base_build:
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- main
|
||||
requires:
|
||||
- setup
|
||||
- sizebot:
|
||||
filters:
|
||||
branches:
|
||||
ignore:
|
||||
- main
|
||||
requires:
|
||||
- get_base_build
|
||||
- yarn_build_combined
|
||||
- yarn_lint_build:
|
||||
requires:
|
||||
- yarn_build_combined
|
||||
fuzz_tests:
|
||||
unless: << pipeline.parameters.prerelease_commit_sha >>
|
||||
triggers:
|
||||
- schedule:
|
||||
# Fuzz tests run hourly
|
||||
@@ -585,9 +514,66 @@ workflows:
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
- main
|
||||
jobs:
|
||||
- setup
|
||||
- test_fuzz:
|
||||
requires:
|
||||
- setup
|
||||
|
||||
# Used to publish a prerelease manually via the command line
|
||||
publish_preleases:
|
||||
when: << pipeline.parameters.prerelease_commit_sha >>
|
||||
jobs:
|
||||
- setup
|
||||
- publish_prerelease:
|
||||
name: Publish to Next channel
|
||||
requires:
|
||||
- setup
|
||||
commit_sha: << pipeline.parameters.prerelease_commit_sha >>
|
||||
release_channel: stable
|
||||
dist_tag: "next,alpha"
|
||||
- publish_prerelease:
|
||||
name: Publish to Experimental channel
|
||||
requires:
|
||||
# NOTE: Intentionally running these jobs sequentially because npm
|
||||
# will sometimes fail if you try to concurrently publish two
|
||||
# different versions of the same package, even if they use different
|
||||
# dist tags.
|
||||
- Publish to Next channel
|
||||
commit_sha: << pipeline.parameters.prerelease_commit_sha >>
|
||||
release_channel: experimental
|
||||
dist_tag: experimental
|
||||
|
||||
# Publishes on a cron schedule
|
||||
publish_preleases_nightly:
|
||||
unless: << pipeline.parameters.prerelease_commit_sha >>
|
||||
triggers:
|
||||
- schedule:
|
||||
# At 10 minutes past 16:00 on Mon, Tue, Wed, Thu, and Fri
|
||||
cron: "10 16 * * 1,2,3,4,5"
|
||||
filters:
|
||||
branches:
|
||||
only:
|
||||
- main
|
||||
jobs:
|
||||
- setup
|
||||
- publish_prerelease:
|
||||
name: Publish to Next channel
|
||||
requires:
|
||||
- setup
|
||||
commit_sha: << pipeline.git.revision >>
|
||||
release_channel: stable
|
||||
dist_tag: "next,alpha"
|
||||
- publish_prerelease:
|
||||
name: Publish to Experimental channel
|
||||
requires:
|
||||
# NOTE: Intentionally running these jobs sequentially because npm
|
||||
# will sometimes fail if you try to concurrently publish two
|
||||
# different versions of the same package, even if they use different
|
||||
# dist tags.
|
||||
- Publish to Next channel
|
||||
commit_sha: << pipeline.git.revision >>
|
||||
release_channel: experimental
|
||||
dist_tag: experimental
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"packages": ["packages/react", "packages/react-dom", "packages/scheduler"],
|
||||
"buildCommand": "build --type=NODE react/index,react-dom/index,react-dom/server,react-dom/test-utils,scheduler/index,scheduler/tracing",
|
||||
"buildCommand": "build --type=NODE react/index,react-dom/index,react-dom/server,react-dom/test-utils,scheduler/index,react/jsx-runtime,react/jsx-dev-runtime",
|
||||
"node": "12",
|
||||
"publishDirectory": {
|
||||
"react": "build/node_modules/react",
|
||||
"react-dom": "build/node_modules/react-dom",
|
||||
"scheduler": "build/node_modules/scheduler"
|
||||
},
|
||||
"sandboxes": ["new"]
|
||||
"sandboxes": ["new"],
|
||||
"silent": true
|
||||
}
|
||||
|
||||
37
.eslintrc.js
37
.eslintrc.js
@@ -48,6 +48,7 @@ module.exports = {
|
||||
'jsx-quotes': [ERROR, 'prefer-double'],
|
||||
'keyword-spacing': [ERROR, {after: true, before: true}],
|
||||
'no-bitwise': OFF,
|
||||
'no-console': OFF,
|
||||
'no-inner-declarations': [ERROR, 'functions'],
|
||||
'no-multi-spaces': ERROR,
|
||||
'no-restricted-globals': [ERROR].concat(restrictedGlobals),
|
||||
@@ -61,6 +62,8 @@ module.exports = {
|
||||
'space-before-blocks': ERROR,
|
||||
'space-before-function-paren': OFF,
|
||||
'valid-typeof': [ERROR, {requireStringLiterals: true}],
|
||||
// Flow fails with with non-string literal keys
|
||||
'no-useless-computed-key': OFF,
|
||||
|
||||
// We apply these settings to files that should run on Node.
|
||||
// They can't use JSX or ES6 modules, and must be in strict mode.
|
||||
@@ -74,6 +77,8 @@ module.exports = {
|
||||
// deal. But I turned it off because loading the plugin causes some obscure
|
||||
// syntax error and it didn't seem worth investigating.
|
||||
'max-len': OFF,
|
||||
// Prettier forces semicolons in a few places
|
||||
'flowtype/object-type-delimiter': OFF,
|
||||
|
||||
// React & JSX
|
||||
// Our transforms set this automatically
|
||||
@@ -111,13 +116,8 @@ module.exports = {
|
||||
'react-internal/no-cross-fork-types': [
|
||||
ERROR,
|
||||
{
|
||||
old: [
|
||||
'firstEffect',
|
||||
'nextEffect',
|
||||
// Disabled because it's also used by the Hook type.
|
||||
// 'lastEffect',
|
||||
],
|
||||
new: ['subtreeFlags'],
|
||||
old: [],
|
||||
new: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -172,16 +172,27 @@ module.exports = {
|
||||
rules: {
|
||||
'react-internal/no-production-logging': OFF,
|
||||
'react-internal/warning-args': OFF,
|
||||
|
||||
// Disable accessibility checks
|
||||
'jsx-a11y/aria-role': OFF,
|
||||
'jsx-a11y/no-noninteractive-element-interactions': OFF,
|
||||
'jsx-a11y/no-static-element-interactions': OFF,
|
||||
'jsx-a11y/role-has-required-aria-props': OFF,
|
||||
'jsx-a11y/no-noninteractive-tabindex': OFF,
|
||||
'jsx-a11y/tabindex-no-positive': OFF,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['packages/react-native-renderer/**/*.js'],
|
||||
files: [
|
||||
'packages/react-native-renderer/**/*.js',
|
||||
'packages/react-server-native-relay/**/*.js',
|
||||
],
|
||||
globals: {
|
||||
nativeFabricUIManager: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['packages/react-transport-dom-webpack/**/*.js'],
|
||||
files: ['packages/react-server-dom-webpack/**/*.js'],
|
||||
globals: {
|
||||
__webpack_chunk_load__: true,
|
||||
__webpack_require__: true,
|
||||
@@ -196,14 +207,14 @@ module.exports = {
|
||||
],
|
||||
|
||||
globals: {
|
||||
SharedArrayBuffer: true,
|
||||
|
||||
spyOnDev: true,
|
||||
spyOnDevAndProd: true,
|
||||
spyOnProd: true,
|
||||
__PROFILE__: true,
|
||||
__UMD__: true,
|
||||
__EXPERIMENTAL__: true,
|
||||
__EXTENSION__: true,
|
||||
__PROFILE__: true,
|
||||
__TEST__: true,
|
||||
__UMD__: true,
|
||||
__VARIANT__: true,
|
||||
gate: true,
|
||||
trustedTypes: true,
|
||||
|
||||
81
.github/ISSUE_TEMPLATE/devtools_bug_report.yml
vendored
Normal file
81
.github/ISSUE_TEMPLATE/devtools_bug_report.yml
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
name: "⚛️ 🛠 DevTools bug report"
|
||||
description: "Report a problem with React DevTools. Please provide enough information that we can reproduce the problem."
|
||||
title: "[DevTools Bug]: "
|
||||
labels: ["Component: Developer Tools", "Type: Bug", "Status: Unconfirmed"]
|
||||
body:
|
||||
- type: input
|
||||
attributes:
|
||||
label: Website or app
|
||||
description: |
|
||||
Which website or app were you using when the bug happened?
|
||||
|
||||
This should be a public URL, GitHub repo, or Code Sandbox app so the React team can reproduce the error being reported. (Please no localhost URLs.)
|
||||
placeholder: |
|
||||
e.g. website URL, public GitHub repo, or Code Sandbox app
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Repro steps
|
||||
description: |
|
||||
What were you doing on the website or app when the bug happened? Detailed information helps maintainers reproduce and fix bugs.
|
||||
|
||||
Issues filed without repro steps will be closed.
|
||||
placeholder: |
|
||||
Example bug report:
|
||||
1. Log in with username/password
|
||||
2. Click "Messages" on the left menu
|
||||
3. Open any message in the list
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: How often does this bug happen?
|
||||
description: |
|
||||
Following the repro steps above, how easily are you able to reproduce this bug?
|
||||
options:
|
||||
- Every time
|
||||
- Often
|
||||
- Sometimes
|
||||
- Only once
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: automated_package
|
||||
attributes:
|
||||
label: DevTools package (automated)
|
||||
description: |
|
||||
Please do not edit this field.
|
||||
- type: input
|
||||
id: automated_version
|
||||
attributes:
|
||||
label: DevTools version (automated)
|
||||
description: |
|
||||
Please do not edit this field.
|
||||
- type: input
|
||||
id: automated_error_message
|
||||
attributes:
|
||||
label: Error message (automated)
|
||||
description: |
|
||||
Please do not edit this field.
|
||||
- type: textarea
|
||||
id: automated_call_stack
|
||||
attributes:
|
||||
label: Error call stack (automated)
|
||||
description: |
|
||||
Please do not edit this field.
|
||||
render: text
|
||||
- type: textarea
|
||||
id: automated_component_stack
|
||||
attributes:
|
||||
label: Error component stack (automated)
|
||||
description: |
|
||||
Please do not edit this field.
|
||||
render: text
|
||||
- type: textarea
|
||||
id: automated_github_query_string
|
||||
attributes:
|
||||
label: GitHub query string (automated)
|
||||
description: |
|
||||
Please do not edit this field.
|
||||
render: text
|
||||
11
.github/ISSUE_TEMPLATE/react_18.md
vendored
Normal file
11
.github/ISSUE_TEMPLATE/react_18.md
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
name: "💬 React 18"
|
||||
about: Bug reports, questions, and general feedback about React 18
|
||||
title: 'React 18 '
|
||||
labels: 'Type: Discussion, React 18'
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
Ask a question or share feedback about the React 18 release here.
|
||||
-->
|
||||
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -8,7 +8,7 @@
|
||||
2. Run `yarn` in the repository root.
|
||||
3. If you've fixed a bug or added code that should be tested, add tests!
|
||||
4. Ensure the test suite passes (`yarn test`). Tip: `yarn test --watch TestName` is helpful in development.
|
||||
5. Run `yarn test-prod` to test in the production environment. It supports the same options as `yarn test`.
|
||||
5. Run `yarn test --prod` to test in the production environment. It supports the same options as `yarn test`.
|
||||
6. If you need a debugger, run `yarn debug-test --watch TestName`, open `chrome://inspect`, and press "Inspect".
|
||||
7. Format your code with [prettier](https://github.com/prettier/prettier) (`yarn prettier`).
|
||||
8. Make sure your code lints (`yarn lint`). Tip: `yarn linc` to only check changed files.
|
||||
|
||||
205
.github/workflows/devtools_check_repro.yml
vendored
Normal file
205
.github/workflows/devtools_check_repro.yml
vendored
Normal file
@@ -0,0 +1,205 @@
|
||||
name: DevTools Check for bug repro
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
issue_comment:
|
||||
types: [created, edited]
|
||||
|
||||
jobs:
|
||||
check-repro:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/github-script@v3
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const URL_REGEXP = /### Website or app[\r\n]+([^#]+)###/m;
|
||||
const REPRO_STEPS_REGEXP = /### Repro steps[\r\n]+([^#]+)###/m;
|
||||
const LABEL_NEEDS_MORE_INFORMATION = "Resolution: Needs More Information";
|
||||
const LABEL_UNCONFIRMED = "Status: Unconfirmed";
|
||||
|
||||
function debug(...args) {
|
||||
core.info(args.map(JSON.stringify).join(' '));
|
||||
}
|
||||
|
||||
if (context.payload.comment) {
|
||||
debug('Ignoring comment update.');
|
||||
return;
|
||||
}
|
||||
|
||||
const user = context.payload.sender.login;
|
||||
const issue = context.payload.issue;
|
||||
const body = issue.body;
|
||||
|
||||
const urlMatch = body.match(URL_REGEXP);
|
||||
const reproStepsMatch = body.match(REPRO_STEPS_REGEXP);
|
||||
|
||||
const url = urlMatch !== null ? urlMatch[1].trim() : null;
|
||||
const reproSteps = reproStepsMatch !== null ? reproStepsMatch[1].trim() : null;
|
||||
|
||||
if (!url || !reproSteps) {
|
||||
debug('This issue is not a DevTools bug report.');
|
||||
return;
|
||||
}
|
||||
|
||||
debug(`found URL "${url}"`);
|
||||
debug(`found repro steps "${reproSteps}"`);
|
||||
|
||||
async function createComment(comment) {
|
||||
// Format
|
||||
comment = comment
|
||||
.split("\n")
|
||||
.map((line) => line.trim())
|
||||
.join("\n")
|
||||
.trim();
|
||||
|
||||
await github.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: comment,
|
||||
});
|
||||
}
|
||||
|
||||
async function getGitHubActionComments() {
|
||||
debug(`Loading existing comments...`);
|
||||
|
||||
const comments = await github.issues.listComments({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
});
|
||||
|
||||
return comments.data.filter(comment => {
|
||||
debug(`comment by user: "${comment.user.login}"`);
|
||||
return comment.user.login === 'github-actions[bot]';
|
||||
});
|
||||
}
|
||||
|
||||
async function getIssueLabels() {
|
||||
const issues = await github.issues.listLabelsOnIssue({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
});
|
||||
|
||||
return issues.data;
|
||||
}
|
||||
|
||||
async function updateIssue(state, assignees = []) {
|
||||
await github.issues.update({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
state,
|
||||
assignees,
|
||||
});
|
||||
}
|
||||
|
||||
async function closeWithComment(comment) {
|
||||
if (issue.state !== 'open') {
|
||||
debug(`Issue is not open`);
|
||||
return;
|
||||
}
|
||||
|
||||
const labels = await getIssueLabels();
|
||||
const label = labels.find(label => label.name === LABEL_UNCONFIRMED);
|
||||
if (!label) {
|
||||
debug(`Issue was not opened via DevTools bug report template`);
|
||||
return;
|
||||
}
|
||||
|
||||
const comments = await getGitHubActionComments();
|
||||
if (comments.length > 0) {
|
||||
debug(`Already commented on issue; won't comment again`);
|
||||
return;
|
||||
}
|
||||
|
||||
debug(`Missing required information`);
|
||||
|
||||
await github.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: [LABEL_NEEDS_MORE_INFORMATION],
|
||||
});
|
||||
|
||||
await createComment(comment);
|
||||
await updateIssue('closed', [user]);
|
||||
}
|
||||
|
||||
async function openWithComment(comment) {
|
||||
if (issue.state !== 'closed') {
|
||||
debug(`Issue is already open`);
|
||||
return;
|
||||
}
|
||||
|
||||
const labels = await getIssueLabels();
|
||||
const label = labels.find(label => label.name === LABEL_NEEDS_MORE_INFORMATION);
|
||||
if (!label) {
|
||||
debug(`Issue was not tagged as needs information`);
|
||||
return;
|
||||
}
|
||||
|
||||
const comments = await getGitHubActionComments();
|
||||
if (comments.length === 0) {
|
||||
debug(`Issue was closed by someone else; won't reopen`);
|
||||
return;
|
||||
}
|
||||
|
||||
debug(`Re-opening closed issue`);
|
||||
|
||||
await github.issues.removeLabel({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: LABEL_NEEDS_MORE_INFORMATION,
|
||||
});
|
||||
|
||||
await createComment(comment);
|
||||
await updateIssue('open');
|
||||
}
|
||||
|
||||
const PROBABLY_NOT_A_URL_REGEX = /(^Chrome$|^Firefox$| Website)/i;
|
||||
|
||||
const COMMENT_HEADER = `
|
||||
@${user}: We're sorry you've seen this error. ❤️
|
||||
`.trim();
|
||||
|
||||
const COMMENT_FOOTER = `
|
||||
Please help us by providing a link to a CodeSandbox (https://codesandbox.io/s/new), a repository on GitHub, or a minimal code example that reproduces the problem. (Screenshots or videos can also be helpful if they help provide context on how to repro the bug.)
|
||||
|
||||
Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve
|
||||
|
||||
Issues without repros are automatically closed but we will re-open if you update with repro info.
|
||||
`.trim();
|
||||
|
||||
if (url.includes("localhost")) {
|
||||
closeWithComment(`
|
||||
${COMMENT_HEADER}
|
||||
|
||||
Unfortunately the URL you provided ("localhost") is not publicly accessible. (This means that we will not be able to reproduce the problem you're reporting.)
|
||||
|
||||
${COMMENT_FOOTER}
|
||||
`);
|
||||
} else if (url.length < 10 || url.match(PROBABLY_NOT_A_URL_REGEX)) {
|
||||
closeWithComment(`
|
||||
${COMMENT_HEADER}
|
||||
|
||||
It looks like you forgot to specify a valid URL. (This means that we will not be able to reproduce the problem you're reporting.)
|
||||
|
||||
${COMMENT_FOOTER}
|
||||
`);
|
||||
} else if (reproSteps.length < 25) {
|
||||
closeWithComment(`
|
||||
${COMMENT_HEADER}
|
||||
|
||||
Unfortunately, it doesn't look like this issue has enough info for one of us to reproduce and fix it though.
|
||||
|
||||
${COMMENT_FOOTER}
|
||||
`);
|
||||
} else {
|
||||
openWithComment(`
|
||||
Thank you for providing repro steps! Re-opening issue now for triage.
|
||||
`);
|
||||
}
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -8,6 +8,7 @@ scripts/flow/*/.flowconfig
|
||||
_SpecRunner.html
|
||||
__benchmarks__
|
||||
build/
|
||||
build2/
|
||||
remote-repo/
|
||||
coverage/
|
||||
.module-cache
|
||||
|
||||
3
AUTHORS
3
AUTHORS
@@ -608,7 +608,6 @@ Ludovico Fischer <livrerie@gmail.com>
|
||||
Luigy Leon <luichi.19@gmail.com>
|
||||
Luke Belliveau <luke.belliveau@gmail.com>
|
||||
Luke Horvat <lukehorvat@gmail.com>
|
||||
Lutz Rosema <terabaud@gmail.com>
|
||||
MICHAEL JACKSON <mjijackson@gmail.com>
|
||||
MIKAMI Yoshiyuki <yoshuki@saikyoline.jp>
|
||||
Maciej Kasprzyk <kapustka.maciek@gmail.com>
|
||||
@@ -671,7 +670,7 @@ Matthew Shotton <matthew.shotton@bbc.co.uk>
|
||||
Matthias Le Brun <mlbli@me.com>
|
||||
Matti Nelimarkka <matti.nelimarkka@hiit.fi>
|
||||
Mattijs Kneppers <mattijs@arttech.nl>
|
||||
Max Donchenko <wereya2@yandex.ru>
|
||||
Max Donchenko <maxx.donchenko@gmail.com>
|
||||
Max F. Albrecht <1@178.is>
|
||||
Max Heiber <max.heiber@gmail.com>
|
||||
Max Stoiber <contact@mstoiber.com>
|
||||
|
||||
120
CHANGELOG.md
120
CHANGELOG.md
@@ -1,3 +1,110 @@
|
||||
## 17.0.2 (March 22, 2021)
|
||||
|
||||
### React DOM
|
||||
|
||||
* Remove an unused dependency to address the [`SharedArrayBuffer` cross-origin isolation warning](https://developer.chrome.com/blog/enabling-shared-array-buffer/). ([@koba04](https://github.com/koba04) and [@bvaughn](https://github.com/bvaughn) in [#20831](https://github.com/facebook/react/pull/20831), [#20832](https://github.com/facebook/react/pull/20832), and [#20840](https://github.com/facebook/react/pull/20840))
|
||||
|
||||
## 17.0.1 (October 22, 2020)
|
||||
|
||||
### React DOM
|
||||
|
||||
* Fix a crash in IE11. ([@gaearon](https://github.com/gaearon) in [#20071](https://github.com/facebook/react/pull/20071))
|
||||
|
||||
## 17.0.0 (October 20, 2020)
|
||||
|
||||
Today, we are releasing React 17!
|
||||
|
||||
**[Learn more about React 17 and how to update to it on the official React blog.](https://reactjs.org/blog/2020/10/20/react-v17.html)**
|
||||
|
||||
### React
|
||||
|
||||
* Add `react/jsx-runtime` and `react/jsx-dev-runtime` for the [new JSX transform](https://babeljs.io/blog/2020/03/16/7.9.0#a-new-jsx-transform-11154-https-githubcom-babel-babel-pull-11154). ([@lunaruan](https://github.com/lunaruan) in [#18299](https://github.com/facebook/react/pull/18299))
|
||||
* Build component stacks from native error frames. ([@sebmarkbage](https://github.com/sebmarkbage) in [#18561](https://github.com/facebook/react/pull/18561))
|
||||
* Allow to specify `displayName` on context for improved stacks. ([@eps1lon](https://github.com/eps1lon) in [#18224](https://github.com/facebook/react/pull/18224))
|
||||
* Prevent `'use strict'` from leaking in the UMD bundles. ([@koba04](https://github.com/koba04) in [#19614](https://github.com/facebook/react/pull/19614))
|
||||
* Stop using `fb.me` for redirects. ([@cylim](https://github.com/cylim) in [#19598](https://github.com/facebook/react/pull/19598))
|
||||
|
||||
### React DOM
|
||||
|
||||
* Delegate events to roots instead of `document`. ([@trueadm](https://github.com/trueadm) in [#18195](https://github.com/facebook/react/pull/18195) and [others](https://github.com/facebook/react/pulls?q=is%3Apr+author%3Atrueadm+modern+event+is%3Amerged))
|
||||
* Clean up all effects before running any next effects. ([@bvaughn](https://github.com/bvaughn) in [#17947](https://github.com/facebook/react/pull/17947))
|
||||
* Run `useEffect` cleanup functions asynchronously. ([@bvaughn](https://github.com/bvaughn) in [#17925](https://github.com/facebook/react/pull/17925))
|
||||
* Use browser `focusin` and `focusout` for `onFocus` and `onBlur`. ([@trueadm](https://github.com/trueadm) in [#19186](https://github.com/facebook/react/pull/19186))
|
||||
* Make all `Capture` events use the browser capture phase. ([@trueadm](https://github.com/trueadm) in [#19221](https://github.com/facebook/react/pull/19221))
|
||||
* Don't emulate bubbling of the `onScroll` event. ([@gaearon](https://github.com/gaearon) in [#19464](https://github.com/facebook/react/pull/19464))
|
||||
* Throw if `forwardRef` or `memo` component returns `undefined`. ([@gaearon](https://github.com/gaearon) in [#19550](https://github.com/facebook/react/pull/19550))
|
||||
* Remove event pooling. ([@trueadm](https://github.com/trueadm) in [#18969](https://github.com/facebook/react/pull/18969))
|
||||
* Stop exposing internals that won’t be needed by React Native Web. ([@necolas](https://github.com/necolas) in [#18483](https://github.com/facebook/react/pull/18483))
|
||||
* Attach all known event listeners when the root mounts. ([@gaearon](https://github.com/gaearon) in [#19659](https://github.com/facebook/react/pull/19659))
|
||||
* Disable `console` in the second render pass of DEV mode double render. ([@sebmarkbage](https://github.com/sebmarkbage) in [#18547](https://github.com/facebook/react/pull/18547))
|
||||
* Deprecate the undocumented and misleading `ReactTestUtils.SimulateNative` API. ([@gaearon](https://github.com/gaearon) in [#13407](https://github.com/facebook/react/pull/13407))
|
||||
* Rename private field names used in the internals. ([@gaearon](https://github.com/gaearon) in [#18377](https://github.com/facebook/react/pull/18377))
|
||||
* Don't call User Timing API in development. ([@gaearon](https://github.com/gaearon) in [#18417](https://github.com/facebook/react/pull/18417))
|
||||
* Disable console during the repeated render in Strict Mode. ([@sebmarkbage](https://github.com/sebmarkbage) in [#18547](https://github.com/facebook/react/pull/18547))
|
||||
* In Strict Mode, double-render components without Hooks too. ([@eps1lon](https://github.com/eps1lon) in [#18430](https://github.com/facebook/react/pull/18430))
|
||||
* Allow calling `ReactDOM.flushSync` during lifecycle methods (but warn). ([@sebmarkbage](https://github.com/sebmarkbage) in [#18759](https://github.com/facebook/react/pull/18759))
|
||||
* Add the `code` property to the keyboard event objects. ([@bl00mber](https://github.com/bl00mber) in [#18287](https://github.com/facebook/react/pull/18287))
|
||||
* Add the `disableRemotePlayback` property for `video` elements. ([@tombrowndev](https://github.com/tombrowndev) in [#18619](https://github.com/facebook/react/pull/18619))
|
||||
* Add the `enterKeyHint` property for `input` elements. ([@eps1lon](https://github.com/eps1lon) in [#18634](https://github.com/facebook/react/pull/18634))
|
||||
* Warn when no `value` is provided to `<Context.Provider>`. ([@charlie1404](https://github.com/charlie1404) in [#19054](https://github.com/facebook/react/pull/19054))
|
||||
* Warn when `memo` or `forwardRef` components return `undefined`. ([@bvaughn](https://github.com/bvaughn) in [#19550](https://github.com/facebook/react/pull/19550))
|
||||
* Improve the error message for invalid updates. ([@JoviDeCroock](https://github.com/JoviDeCroock) in [#18316](https://github.com/facebook/react/pull/18316))
|
||||
* Exclude forwardRef and memo from stack frames. ([@sebmarkbage](https://github.com/sebmarkbage) in [#18559](https://github.com/facebook/react/pull/18559))
|
||||
* Improve the error message when switching between controlled and uncontrolled inputs. ([@vcarl](https://github.com/vcarl) in [#17070](https://github.com/facebook/react/pull/17070))
|
||||
* Keep `onTouchStart`, `onTouchMove`, and `onWheel` passive. ([@gaearon](https://github.com/gaearon) in [#19654](https://github.com/facebook/react/pull/19654))
|
||||
* Fix `setState` hanging in development inside a closed iframe. ([@gaearon](https://github.com/gaearon) in [#19220](https://github.com/facebook/react/pull/19220))
|
||||
* Fix rendering bailout for lazy components with `defaultProps`. ([@jddxf](https://github.com/jddxf) in [#18539](https://github.com/facebook/react/pull/18539))
|
||||
* Fix a false positive warning when `dangerouslySetInnerHTML` is `undefined`. ([@eps1lon](https://github.com/eps1lon) in [#18676](https://github.com/facebook/react/pull/18676))
|
||||
* Fix Test Utils with non-standard `require` implementation. ([@just-boris](https://github.com/just-boris) in [#18632](https://github.com/facebook/react/pull/18632))
|
||||
* Fix `onBeforeInput` reporting an incorrect `event.type`. ([@eps1lon](https://github.com/eps1lon) in [#19561](https://github.com/facebook/react/pull/19561))
|
||||
* Fix `event.relatedTarget` reported as `undefined` in Firefox. ([@claytercek](https://github.com/claytercek) in [#19607](https://github.com/facebook/react/pull/19607))
|
||||
* Fix "unspecified error" in IE11. ([@hemakshis](https://github.com/hemakshis) in [#19664](https://github.com/facebook/react/pull/19664))
|
||||
* Fix rendering into a shadow root. ([@Jack-Works](https://github.com/Jack-Works) in [#15894](https://github.com/facebook/react/pull/15894))
|
||||
* Fix `movementX/Y` polyfill with capture events. ([@gaearon](https://github.com/gaearon) in [#19672](https://github.com/facebook/react/pull/19672))
|
||||
* Use delegation for `onSubmit` and `onReset` events. ([@gaearon](https://github.com/gaearon) in [#19333](https://github.com/facebook/react/pull/19333))
|
||||
* Improve memory usage. ([@trueadm](https://github.com/trueadm) in [#18970](https://github.com/facebook/react/pull/18970))
|
||||
|
||||
### React DOM Server
|
||||
|
||||
* Make `useCallback` behavior consistent with `useMemo` for the server renderer. ([@alexmckenley](https://github.com/alexmckenley) in [#18783](https://github.com/facebook/react/pull/18783))
|
||||
* Fix state leaking when a function component throws. ([@pmaccart](https://github.com/pmaccart) in [#19212](https://github.com/facebook/react/pull/19212))
|
||||
|
||||
### React Test Renderer
|
||||
|
||||
* Improve `findByType` error message. ([@henryqdineen](https://github.com/henryqdineen) in [#17439](https://github.com/facebook/react/pull/17439))
|
||||
|
||||
### Concurrent Mode (Experimental)
|
||||
|
||||
* Revamp the priority batching heuristics. ([@acdlite](https://github.com/acdlite) in [#18796](https://github.com/facebook/react/pull/18796))
|
||||
* Add the `unstable_` prefix before the experimental APIs. ([@acdlite](https://github.com/acdlite) in [#18825](https://github.com/facebook/react/pull/18825))
|
||||
* Remove `unstable_discreteUpdates` and `unstable_flushDiscreteUpdates`. ([@trueadm](https://github.com/trueadm) in [#18825](https://github.com/facebook/react/pull/18825))
|
||||
* Remove the `timeoutMs` argument. ([@acdlite](https://github.com/acdlite) in [#19703](https://github.com/facebook/react/pull/19703))
|
||||
* Disable `<div hidden />` prerendering in favor of a different future API. ([@acdlite](https://github.com/acdlite) in [#18917](https://github.com/facebook/react/pull/18917))
|
||||
* Add `unstable_expectedLoadTime` to Suspense for CPU-bound trees. ([@acdlite](https://github.com/acdlite) in [#19936](https://github.com/facebook/react/pull/19936))
|
||||
* Add an experimental `unstable_useOpaqueIdentifier` Hook. ([@lunaruan](https://github.com/lunaruan) in [#17322](https://github.com/facebook/react/pull/17322))
|
||||
* Add an experimental `unstable_startTransition` API. ([@rickhanlonii](https://github.com/rickhanlonii) in [#19696](https://github.com/facebook/react/pull/19696))
|
||||
* Using `act` in the test renderer no longer flushes Suspense fallbacks. ([@acdlite](https://github.com/acdlite) in [#18596](https://github.com/facebook/react/pull/18596))
|
||||
* Use global render timeout for CPU Suspense. ([@sebmarkbage](https://github.com/sebmarkbage) in [#19643](https://github.com/facebook/react/pull/19643))
|
||||
* Clear the existing root content before mounting. ([@bvaughn](https://github.com/bvaughn) in [#18730](https://github.com/facebook/react/pull/18730))
|
||||
* Fix a bug with error boundaries. ([@acdlite](https://github.com/acdlite) in [#18265](https://github.com/facebook/react/pull/18265))
|
||||
* Fix a bug causing dropped updates in a suspended tree. ([@acdlite](https://github.com/acdlite) in [#18384](https://github.com/facebook/react/pull/18384) and [#18457](https://github.com/facebook/react/pull/18457))
|
||||
* Fix a bug causing dropped render phase updates. ([@acdlite](https://github.com/acdlite) in [#18537](https://github.com/facebook/react/pull/18537))
|
||||
* Fix a bug in SuspenseList. ([@sebmarkbage](https://github.com/sebmarkbage) in [#18412](https://github.com/facebook/react/pull/18412))
|
||||
* Fix a bug causing Suspense fallback to show too early. ([@acdlite](https://github.com/acdlite) in [#18411](https://github.com/facebook/react/pull/18411))
|
||||
* Fix a bug with class components inside SuspenseList. ([@sebmarkbage](https://github.com/sebmarkbage) in [#18448](https://github.com/facebook/react/pull/18448))
|
||||
* Fix a bug with inputs that may cause updates to be dropped. ([@jddxf](https://github.com/jddxf) in [#18515](https://github.com/facebook/react/pull/18515) and [@acdlite](https://github.com/acdlite) in [#18535](https://github.com/facebook/react/pull/18535))
|
||||
* Fix a bug causing Suspense fallback to get stuck. ([@acdlite](https://github.com/acdlite) in [#18663](https://github.com/facebook/react/pull/18663))
|
||||
* Don't cut off the tail of a SuspenseList if hydrating. ([@sebmarkbage](https://github.com/sebmarkbage) in [#18854](https://github.com/facebook/react/pull/18854))
|
||||
* Fix a bug in `useMutableSource` that may happen when `getSnapshot` changes. ([@bvaughn](https://github.com/bvaughn) in [#18297](https://github.com/facebook/react/pull/18297))
|
||||
* Fix a tearing bug in `useMutableSource`. ([@bvaughn](https://github.com/bvaughn) in [#18912](https://github.com/facebook/react/pull/18912))
|
||||
* Warn if calling setState outside of render but before commit. ([@sebmarkbage](https://github.com/sebmarkbage) in [#18838](https://github.com/facebook/react/pull/18838))
|
||||
|
||||
## 16.14.0 (October 14, 2020)
|
||||
|
||||
### React
|
||||
|
||||
* Add support for the [new JSX transform](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html). ([@lunaruan](https://github.com/lunaruan) in [#18299](https://github.com/facebook/react/pull/18299))
|
||||
|
||||
## 16.13.1 (March 19, 2020)
|
||||
|
||||
### React DOM
|
||||
@@ -770,6 +877,12 @@ Starting with 16.1.0, we will no longer be publishing new releases on Bower. You
|
||||
- There is no `react-with-addons.js` build anymore. All compatible addons are published separately on npm, and have single-file browser versions if you need them.
|
||||
- The deprecations introduced in 15.x have been removed from the core package. `React.createClass` is now available as create-react-class, `React.PropTypes` as prop-types, `React.DOM` as react-dom-factories, react-addons-test-utils as react-dom/test-utils, and shallow renderer as react-test-renderer/shallow. See [15.5.0](https://reactjs.org/blog/2017/04/07/react-v15.5.0.html) and [15.6.0](https://reactjs.org/blog/2017/06/13/react-v15.6.0.html) blog posts for instructions on migrating code and automated codemods.
|
||||
|
||||
## 15.7.0 (October 14, 2020)
|
||||
|
||||
### React
|
||||
|
||||
* Backport support for the [new JSX transform](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) to 15.x. ([@lunaruan](https://github.com/lunaruan) in [#18299](https://github.com/facebook/react/pull/18299) and [@gaearon](https://github.com/gaearon) in [#20024](https://github.com/facebook/react/pull/20024))
|
||||
|
||||
## 15.6.2 (September 25, 2017)
|
||||
|
||||
### All Packages
|
||||
@@ -1218,9 +1331,14 @@ Each of these changes will continue to work as before with a new warning until t
|
||||
- Shallow renderer now returns the rendered output from `render()`. ([@simonewebdesign](https://github.com/simonewebdesign) in [#5411](https://github.com/facebook/react/pull/5411))
|
||||
- React no longer depends on ES5 *shams* for `Object.create` and `Object.freeze` in older environments. It still, however, requires ES5 *shims* in those environments. ([@dgreensp](https://github.com/dgreensp) in [#4959](https://github.com/facebook/react/pull/4959))
|
||||
- React DOM now allows `data-` attributes with names that start with numbers. ([@nLight](https://github.com/nLight) in [#5216](https://github.com/facebook/react/pull/5216))
|
||||
- React DOM adds a new `suppressContentEditableWarning` prop for components like [Draft.js](https://facebook.github.io/draft-js/) that intentionally manage `contentEditable` children with React. ([@mxstbr](https://github.com/mxstbr) in [#6112](https://github.com/facebook/react/pull/6112))
|
||||
- React DOM adds a new `suppressContentEditableWarning` prop for components like [Draft.js](https://draftjs.org/) that intentionally manage `contentEditable` children with React. ([@mxstbr](https://github.com/mxstbr) in [#6112](https://github.com/facebook/react/pull/6112))
|
||||
- React improves the performance for `createClass()` on complex specs. ([@sophiebits](https://github.com/sophiebits) in [#5550](https://github.com/facebook/react/pull/5550))
|
||||
|
||||
## 0.14.10 (October 14, 2020)
|
||||
|
||||
### React
|
||||
|
||||
* Backport support for the [new JSX transform](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html) to 0.14.x. ([@lunaruan](https://github.com/lunaruan) in [#18299](https://github.com/facebook/react/pull/18299) and [@gaearon](https://github.com/gaearon) in [#20024](https://github.com/facebook/react/pull/20024))
|
||||
|
||||
## 0.14.8 (March 29, 2016)
|
||||
|
||||
|
||||
@@ -52,6 +52,10 @@ project e-mail address, posting via an official social media account, or acting
|
||||
as an appointed representative at an online or offline event. Representation of
|
||||
a project may be further defined and clarified by project maintainers.
|
||||
|
||||
This Code of Conduct also applies outside the project spaces when there is a
|
||||
reasonable belief that an individual's behavior may have a negative impact on
|
||||
the project or its community.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
|
||||
57
ReactVersions.js
Normal file
57
ReactVersions.js
Normal file
@@ -0,0 +1,57 @@
|
||||
'use strict';
|
||||
|
||||
// This module is the single source of truth for versioning packages that we
|
||||
// publish to npm.
|
||||
//
|
||||
// Packages will not be published unless they are added here.
|
||||
//
|
||||
// The @latest channel uses the version as-is, e.g.:
|
||||
//
|
||||
// 18.0.0
|
||||
//
|
||||
// The @next channel appends additional information, with the scheme
|
||||
// <version>-<label>-<commit_sha>, e.g.:
|
||||
//
|
||||
// 18.0.0-alpha-a1c2d3e4
|
||||
//
|
||||
// The @experimental channel doesn't include a version, only a date and a sha, e.g.:
|
||||
//
|
||||
// 0.0.0-experimental-241c4467e-20200129
|
||||
|
||||
const ReactVersion = '18.0.0';
|
||||
|
||||
// The label used by the @next channel. Represents the upcoming release's
|
||||
// stability. Could be "alpha", "beta", "rc", etc.
|
||||
const nextChannelLabel = 'alpha';
|
||||
|
||||
const stablePackages = {
|
||||
'create-subscription': ReactVersion,
|
||||
'eslint-plugin-react-hooks': '4.2.1',
|
||||
'jest-react': '0.12.1',
|
||||
react: ReactVersion,
|
||||
'react-art': ReactVersion,
|
||||
'react-dom': ReactVersion,
|
||||
'react-is': ReactVersion,
|
||||
'react-reconciler': '0.27.0',
|
||||
'react-refresh': '0.11.0',
|
||||
'react-test-renderer': ReactVersion,
|
||||
'use-subscription': '1.6.0',
|
||||
scheduler: '0.21.0',
|
||||
};
|
||||
|
||||
// These packages do not exist in the @next or @latest channel, only
|
||||
// @experimental. We don't use semver, just the commit sha, so this is just a
|
||||
// list of package names instead of a map.
|
||||
const experimentalPackages = [
|
||||
'react-fetch',
|
||||
'react-fs',
|
||||
'react-pg',
|
||||
'react-server-dom-webpack',
|
||||
];
|
||||
|
||||
module.exports = {
|
||||
ReactVersion,
|
||||
nextChannelLabel,
|
||||
stablePackages,
|
||||
experimentalPackages,
|
||||
};
|
||||
416
dangerfile.js
416
dangerfile.js
@@ -7,6 +7,8 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
/* eslint-disable no-for-of-loops/no-for-of-loops */
|
||||
|
||||
// Hi, if this is your first time editing/reading a Dangerfile, here's a summary:
|
||||
// It's a JS runtime which helps you provide continuous feedback inside GitHub.
|
||||
//
|
||||
@@ -26,270 +28,220 @@
|
||||
// `DANGER_GITHUB_API_TOKEN=[ENV_ABOVE] yarn danger pr https://github.com/facebook/react/pull/11865
|
||||
|
||||
const {markdown, danger, warn} = require('danger');
|
||||
const fetch = require('node-fetch');
|
||||
const {promisify} = require('util');
|
||||
const glob = promisify(require('glob'));
|
||||
const gzipSize = require('gzip-size');
|
||||
|
||||
const {generateResultsArray} = require('./scripts/rollup/stats');
|
||||
const {existsSync, readFileSync} = require('fs');
|
||||
const {exec} = require('child_process');
|
||||
const {readFileSync, statSync} = require('fs');
|
||||
|
||||
// This must match the name of the CI job that creates the build artifacts
|
||||
const RELEASE_CHANNEL =
|
||||
process.env.RELEASE_CHANNEL === 'experimental' ? 'experimental' : 'stable';
|
||||
const artifactsJobName =
|
||||
process.env.RELEASE_CHANNEL === 'experimental'
|
||||
? 'process_artifacts_experimental'
|
||||
: 'process_artifacts';
|
||||
const BASE_DIR = 'base-build';
|
||||
const HEAD_DIR = 'build2';
|
||||
|
||||
if (!existsSync('./build/bundle-sizes.json')) {
|
||||
// This indicates the build failed previously.
|
||||
// In that case, there's nothing for the Dangerfile to do.
|
||||
// Exit early to avoid leaving a redundant (and potentially confusing) PR comment.
|
||||
warn(
|
||||
'No bundle size information found. This indicates the build ' +
|
||||
'job failed.'
|
||||
);
|
||||
process.exit(0);
|
||||
const CRITICAL_THRESHOLD = 0.02;
|
||||
const SIGNIFICANCE_THRESHOLD = 0.002;
|
||||
const CRITICAL_ARTIFACT_PATHS = new Set([
|
||||
// We always report changes to these bundles, even if the change is
|
||||
// insiginificant or non-existent.
|
||||
'oss-stable/react-dom/cjs/react-dom.production.min.js',
|
||||
'oss-experimental/react-dom/cjs/react-dom.production.min.js',
|
||||
'facebook-www/ReactDOM-prod.classic.js',
|
||||
'facebook-www/ReactDOM-prod.modern.js',
|
||||
'facebook-www/ReactDOMForked-prod.classic.js',
|
||||
]);
|
||||
|
||||
const kilobyteFormatter = new Intl.NumberFormat('en', {
|
||||
style: 'unit',
|
||||
unit: 'kilobyte',
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
|
||||
function kbs(bytes) {
|
||||
return kilobyteFormatter.format(bytes / 1000);
|
||||
}
|
||||
|
||||
const currentBuildResults = JSON.parse(
|
||||
readFileSync('./build/bundle-sizes.json')
|
||||
);
|
||||
const percentFormatter = new Intl.NumberFormat('en', {
|
||||
style: 'percent',
|
||||
signDisplay: 'exceptZero',
|
||||
minimumFractionDigits: 2,
|
||||
maximumFractionDigits: 2,
|
||||
});
|
||||
|
||||
/**
|
||||
* Generates a Markdown table
|
||||
* @param {string[]} headers
|
||||
* @param {string[][]} body
|
||||
*/
|
||||
function generateMDTable(headers, body) {
|
||||
const tableHeaders = [
|
||||
headers.join(' | '),
|
||||
headers.map(() => ' --- ').join(' | '),
|
||||
];
|
||||
|
||||
const tablebody = body.map(r => r.join(' | '));
|
||||
return tableHeaders.join('\n') + '\n' + tablebody.join('\n');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a user-readable string from a percentage change
|
||||
* @param {number} change
|
||||
* @param {boolean} includeEmoji
|
||||
*/
|
||||
function addPercent(change, includeEmoji) {
|
||||
if (!isFinite(change)) {
|
||||
// When a new package is created
|
||||
return 'n/a';
|
||||
function change(decimal) {
|
||||
if (Number === Infinity) {
|
||||
return 'New file';
|
||||
}
|
||||
const formatted = (change * 100).toFixed(1);
|
||||
if (/^-|^0(?:\.0+)$/.test(formatted)) {
|
||||
return `${formatted}%`;
|
||||
} else {
|
||||
if (includeEmoji) {
|
||||
return `:small_red_triangle:+${formatted}%`;
|
||||
} else {
|
||||
return `+${formatted}%`;
|
||||
}
|
||||
if (decimal === -1) {
|
||||
return 'Deleted';
|
||||
}
|
||||
if (decimal < 0.0001) {
|
||||
return '=';
|
||||
}
|
||||
return percentFormatter.format(decimal);
|
||||
}
|
||||
|
||||
function setBoldness(row, isBold) {
|
||||
if (isBold) {
|
||||
return row.map(element => `**${element}**`);
|
||||
} else {
|
||||
return row;
|
||||
}
|
||||
}
|
||||
const header = `
|
||||
| Name | +/- | Base | Current | +/- gzip | Base gzip | Current gzip |
|
||||
| ---- | --- | ---- | ------- | -------- | --------- | ------------ |`;
|
||||
|
||||
/**
|
||||
* Gets the commit that represents the merge between the current branch
|
||||
* and master.
|
||||
*/
|
||||
function git(args) {
|
||||
return new Promise(res => {
|
||||
exec('git ' + args, (err, stdout, stderr) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
} else {
|
||||
res(stdout.trim());
|
||||
}
|
||||
});
|
||||
});
|
||||
function row(result) {
|
||||
// prettier-ignore
|
||||
return `| ${result.path} | **${change(result.change)}** | ${kbs(result.baseSize)} | ${kbs(result.headSize)} | ${change(result.changeGzip)} | ${kbs(result.baseSizeGzip)} | ${kbs(result.headSizeGzip)}`;
|
||||
}
|
||||
|
||||
(async function() {
|
||||
// Use git locally to grab the commit which represents the place
|
||||
// where the branches differ
|
||||
|
||||
const upstreamRepo = danger.github.pr.base.repo.full_name;
|
||||
if (upstreamRepo !== 'facebook/react') {
|
||||
// Exit unless we're running in the main repo
|
||||
return;
|
||||
}
|
||||
|
||||
markdown(`## Size changes (${RELEASE_CHANNEL})`);
|
||||
|
||||
const upstreamRef = danger.github.pr.base.ref;
|
||||
await git(`remote add upstream https://github.com/facebook/react.git`);
|
||||
await git('fetch upstream');
|
||||
const baseCommit = await git(`merge-base HEAD upstream/${upstreamRef}`);
|
||||
|
||||
let previousBuildResults = null;
|
||||
let headSha;
|
||||
let baseSha;
|
||||
try {
|
||||
let baseCIBuildId = null;
|
||||
const statusesResponse = await fetch(
|
||||
`https://api.github.com/repos/facebook/react/commits/${baseCommit}/status`
|
||||
headSha = (readFileSync(HEAD_DIR + '/COMMIT_SHA') + '').trim();
|
||||
baseSha = (readFileSync(BASE_DIR + '/COMMIT_SHA') + '').trim();
|
||||
} catch {
|
||||
warn(
|
||||
"Failed to read build artifacts. It's possible a build configuration " +
|
||||
'has changed upstream. Try pulling the latest changes from the ' +
|
||||
'main branch.'
|
||||
);
|
||||
const {statuses, state} = await statusesResponse.json();
|
||||
if (state === 'failure') {
|
||||
warn(`Base commit is broken: ${baseCommit}`);
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < statuses.length; i++) {
|
||||
const status = statuses[i];
|
||||
if (status.context === `ci/circleci: ${artifactsJobName}`) {
|
||||
if (status.state === 'success') {
|
||||
baseCIBuildId = /\/facebook\/react\/([0-9]+)/.exec(
|
||||
status.target_url
|
||||
)[1];
|
||||
break;
|
||||
}
|
||||
if (status.state === 'pending') {
|
||||
warn(`Build job for base commit is still pending: ${baseCommit}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (baseCIBuildId === null) {
|
||||
warn(`Could not find build artifacts for base commit: ${baseCommit}`);
|
||||
return;
|
||||
}
|
||||
|
||||
const baseArtifactsInfoResponse = await fetch(
|
||||
`https://circleci.com/api/v1.1/project/github/facebook/react/${baseCIBuildId}/artifacts`
|
||||
);
|
||||
const baseArtifactsInfo = await baseArtifactsInfoResponse.json();
|
||||
|
||||
for (let i = 0; i < baseArtifactsInfo.length; i++) {
|
||||
const info = baseArtifactsInfo[i];
|
||||
if (info.path.endsWith('bundle-sizes.json')) {
|
||||
const resultsResponse = await fetch(info.url);
|
||||
previousBuildResults = await resultsResponse.json();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
warn(`Failed to fetch build artifacts for base commit: ${baseCommit}`);
|
||||
return;
|
||||
}
|
||||
|
||||
if (previousBuildResults === null) {
|
||||
warn(`Could not find build artifacts for base commit: ${baseCommit}`);
|
||||
return;
|
||||
}
|
||||
const resultsMap = new Map();
|
||||
|
||||
// Take the JSON of the build response and
|
||||
// make an array comparing the results for printing
|
||||
const results = generateResultsArray(
|
||||
currentBuildResults,
|
||||
previousBuildResults
|
||||
);
|
||||
// Find all the head (current) artifacts paths.
|
||||
const headArtifactPaths = await glob('**/*.js', {cwd: 'build2'});
|
||||
for (const artifactPath of headArtifactPaths) {
|
||||
try {
|
||||
// This will throw if there's no matching base artifact
|
||||
const baseSize = statSync(BASE_DIR + '/' + artifactPath).size;
|
||||
const baseSizeGzip = gzipSize.fileSync(BASE_DIR + '/' + artifactPath);
|
||||
|
||||
const packagesToShow = results
|
||||
.filter(
|
||||
r =>
|
||||
Math.abs(r.prevFileSizeAbsoluteChange) >= 300 || // bytes
|
||||
Math.abs(r.prevGzipSizeAbsoluteChange) >= 100 // bytes
|
||||
)
|
||||
.map(r => r.packageName);
|
||||
|
||||
if (packagesToShow.length) {
|
||||
let allTables = [];
|
||||
|
||||
// Highlight React and React DOM changes inline
|
||||
// e.g. react: `react.production.min.js`: -3%, `react.development.js`: +4%
|
||||
|
||||
if (packagesToShow.includes('react')) {
|
||||
const reactProd = results.find(
|
||||
r => r.bundleType === 'UMD_PROD' && r.packageName === 'react'
|
||||
);
|
||||
if (
|
||||
reactProd.prevFileSizeChange !== 0 ||
|
||||
reactProd.prevGzipSizeChange !== 0
|
||||
) {
|
||||
const changeSize = addPercent(reactProd.prevFileSizeChange, true);
|
||||
const changeGzip = addPercent(reactProd.prevGzipSizeChange, true);
|
||||
markdown(`React: size: ${changeSize}, gzip: ${changeGzip}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (packagesToShow.includes('react-dom')) {
|
||||
const reactDOMProd = results.find(
|
||||
r => r.bundleType === 'UMD_PROD' && r.packageName === 'react-dom'
|
||||
);
|
||||
if (
|
||||
reactDOMProd.prevFileSizeChange !== 0 ||
|
||||
reactDOMProd.prevGzipSizeChange !== 0
|
||||
) {
|
||||
const changeSize = addPercent(reactDOMProd.prevFileSizeChange, true);
|
||||
const changeGzip = addPercent(reactDOMProd.prevGzipSizeChange, true);
|
||||
markdown(`ReactDOM: size: ${changeSize}, gzip: ${changeGzip}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Show a hidden summary table for all diffs
|
||||
|
||||
// eslint-disable-next-line no-var,no-for-of-loops/no-for-of-loops
|
||||
for (var name of new Set(packagesToShow)) {
|
||||
const thisBundleResults = results.filter(r => r.packageName === name);
|
||||
const changedFiles = thisBundleResults.filter(
|
||||
r => r.prevFileSizeChange !== 0 || r.prevGzipSizeChange !== 0
|
||||
);
|
||||
|
||||
const mdHeaders = [
|
||||
'File',
|
||||
'Filesize Diff',
|
||||
'Gzip Diff',
|
||||
'Prev Size',
|
||||
'Current Size',
|
||||
'Prev Gzip',
|
||||
'Current Gzip',
|
||||
'ENV',
|
||||
];
|
||||
|
||||
const mdRows = changedFiles.map(r => {
|
||||
const isProd = r.bundleType.includes('PROD');
|
||||
return setBoldness(
|
||||
[
|
||||
r.filename,
|
||||
addPercent(r.prevFileSizeChange, isProd),
|
||||
addPercent(r.prevGzipSizeChange, isProd),
|
||||
r.prevSize,
|
||||
r.prevFileSize,
|
||||
r.prevGzip,
|
||||
r.prevGzipSize,
|
||||
r.bundleType,
|
||||
],
|
||||
isProd
|
||||
);
|
||||
const headSize = statSync(HEAD_DIR + '/' + artifactPath).size;
|
||||
const headSizeGzip = gzipSize.fileSync(HEAD_DIR + '/' + artifactPath);
|
||||
resultsMap.set(artifactPath, {
|
||||
path: artifactPath,
|
||||
headSize,
|
||||
headSizeGzip,
|
||||
baseSize,
|
||||
baseSizeGzip,
|
||||
change: (headSize - baseSize) / baseSize,
|
||||
changeGzip: (headSizeGzip - baseSizeGzip) / baseSizeGzip,
|
||||
});
|
||||
} catch {
|
||||
// There's no matching base artifact. This is a new file.
|
||||
const baseSize = 0;
|
||||
const baseSizeGzip = 0;
|
||||
const headSize = statSync(HEAD_DIR + '/' + artifactPath).size;
|
||||
const headSizeGzip = gzipSize.fileSync(HEAD_DIR + '/' + artifactPath);
|
||||
resultsMap.set(artifactPath, {
|
||||
path: artifactPath,
|
||||
headSize,
|
||||
headSizeGzip,
|
||||
baseSize,
|
||||
baseSizeGzip,
|
||||
change: Infinity,
|
||||
changeGzip: Infinity,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
allTables.push(`\n## ${name}`);
|
||||
allTables.push(generateMDTable(mdHeaders, mdRows));
|
||||
// Check for base artifacts that were deleted in the head.
|
||||
const baseArtifactPaths = await glob('**/*.js', {cwd: 'base-build'});
|
||||
for (const artifactPath of baseArtifactPaths) {
|
||||
if (!resultsMap.has(artifactPath)) {
|
||||
const baseSize = statSync(BASE_DIR + '/' + artifactPath).size;
|
||||
const baseSizeGzip = gzipSize.fileSync(BASE_DIR + '/' + artifactPath);
|
||||
const headSize = 0;
|
||||
const headSizeGzip = 0;
|
||||
resultsMap.set(artifactPath, {
|
||||
path: artifactPath,
|
||||
headSize,
|
||||
headSizeGzip,
|
||||
baseSize,
|
||||
baseSizeGzip,
|
||||
change: -1,
|
||||
changeGzip: -1,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const results = Array.from(resultsMap.values());
|
||||
results.sort((a, b) => b.change - a.change);
|
||||
|
||||
let criticalResults = [];
|
||||
for (const artifactPath of CRITICAL_ARTIFACT_PATHS) {
|
||||
const result = resultsMap.get(artifactPath);
|
||||
if (result === undefined) {
|
||||
throw new Error(
|
||||
'Missing expected bundle. If this was an intentional change to the ' +
|
||||
'build configuration, update Dangerfile.js accordingly: ' +
|
||||
artifactPath
|
||||
);
|
||||
}
|
||||
criticalResults.push(row(result));
|
||||
}
|
||||
|
||||
let significantResults = [];
|
||||
for (const result of results) {
|
||||
// If result exceeds critical threshold, add to top section.
|
||||
if (
|
||||
(result.change > CRITICAL_THRESHOLD ||
|
||||
0 - result.change > CRITICAL_THRESHOLD ||
|
||||
// New file
|
||||
result.change === Infinity ||
|
||||
// Deleted file
|
||||
result.change === -1) &&
|
||||
// Skip critical artifacts. We added those earlier, in a fixed order.
|
||||
!CRITICAL_ARTIFACT_PATHS.has(result.path)
|
||||
) {
|
||||
criticalResults.push(row(result));
|
||||
}
|
||||
|
||||
const summary = `
|
||||
<details>
|
||||
<summary>Details of bundled changes.</summary>
|
||||
|
||||
<p>Comparing: ${baseCommit}...${danger.github.pr.head.sha}</p>
|
||||
|
||||
|
||||
${allTables.join('\n')}
|
||||
|
||||
</details>
|
||||
`;
|
||||
markdown(summary);
|
||||
} else {
|
||||
markdown('No significant bundle size changes to report.');
|
||||
// Do the same for results that exceed the significant threshold. These
|
||||
// will go into the bottom, collapsed section. Intentionally including
|
||||
// critical artifacts in this section, too.
|
||||
if (
|
||||
result.change > SIGNIFICANCE_THRESHOLD ||
|
||||
0 - result.change > SIGNIFICANCE_THRESHOLD ||
|
||||
result.change === Infinity ||
|
||||
result.change === -1
|
||||
) {
|
||||
significantResults.push(row(result));
|
||||
}
|
||||
}
|
||||
|
||||
markdown(`
|
||||
Comparing: ${baseSha}...${headSha}
|
||||
|
||||
## Critical size changes
|
||||
|
||||
Includes critical production bundles, as well as any change greater than ${CRITICAL_THRESHOLD *
|
||||
100}%:
|
||||
|
||||
${header}
|
||||
${criticalResults.join('\n')}
|
||||
|
||||
## Significant size changes
|
||||
|
||||
Includes any change greater than ${SIGNIFICANCE_THRESHOLD * 100}%:
|
||||
|
||||
${
|
||||
significantResults.length > 0
|
||||
? `
|
||||
<details>
|
||||
<summary>Expand to show</summary>
|
||||
${header}
|
||||
${significantResults.join('\n')}
|
||||
</details>
|
||||
`
|
||||
: '(No significant changes)'
|
||||
}
|
||||
`);
|
||||
})();
|
||||
|
||||
@@ -26,6 +26,6 @@ Right now, we use a purple outline to call out cases where the assigned property
|
||||
---
|
||||
|
||||
|
||||
This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app).
|
||||
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
|
||||
|
||||
You can find the guide for how to do things in a CRA [here](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md).
|
||||
You can find the guide for how to do things in a CRA [here](https://github.com/facebook/create-react-app/blob/master/packages/cra-template/template/README.md).
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import {unstable_createRoot as createRoot} from 'react-dom';
|
||||
import {createRoot} from 'react-dom';
|
||||
import './index.css';
|
||||
import Router from './Router';
|
||||
|
||||
|
||||
@@ -14,6 +14,18 @@ There are also known bugs and inefficiencies in master so **don't use this fixtu
|
||||
|
||||
## How do I run this fixture?
|
||||
|
||||
### From npm version
|
||||
|
||||
```
|
||||
# 1: Install fixture dependencies
|
||||
cd fixtures/unstable-async/time-slicing/
|
||||
yarn
|
||||
|
||||
# 2: Run the app
|
||||
yarn start
|
||||
```
|
||||
|
||||
### From React source code
|
||||
```shell
|
||||
# 1: Build react from source
|
||||
cd /path/to/react
|
||||
@@ -24,6 +36,9 @@ yarn build react-dom/index,react/index,react-cache,scheduler --type=NODE
|
||||
cd fixtures/unstable-async/time-slicing/
|
||||
yarn
|
||||
|
||||
# 3: Copy React source code over
|
||||
yarn copy-source
|
||||
|
||||
# 3: Run the app
|
||||
yarn start
|
||||
```
|
||||
|
||||
@@ -4,13 +4,14 @@
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"glamor": "^2.20.40",
|
||||
"react": "0.0.0-experimental-269dd6ec5",
|
||||
"react-dom": "0.0.0-experimental-269dd6ec5",
|
||||
"react-markdown": "^3.2.0",
|
||||
"react-scripts": "^1.1.4",
|
||||
"victory": "^0.25.6"
|
||||
},
|
||||
"scripts": {
|
||||
"prestart": "cp -r ../../../build/node_modules/* ./node_modules/",
|
||||
"prebuild": "cp -r ../../../build/node_modules/* ./node_modules/",
|
||||
"copy-source": "cp -r ../../../build/node_modules/* ./node_modules/",
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
|
||||
@@ -32,16 +32,18 @@ body {
|
||||
margin-top: 20px;
|
||||
margin-bottom: 20px;
|
||||
zoom: 1.8;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
label {
|
||||
zoom: 1;
|
||||
margin-right: 50px;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
label.selected {
|
||||
font-weight: bold;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
label:nth-child(1).selected {
|
||||
@@ -56,6 +58,10 @@ label:nth-child(3).selected {
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
input[type="radio" i]:nth-child(1) {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
.chart {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import React, {PureComponent} from 'react';
|
||||
import {flushSync, createRoot} from 'react-dom';
|
||||
import Scheduler from 'scheduler';
|
||||
import React, {PureComponent, unstable_startTransition} from 'react';
|
||||
import {createRoot} from 'react-dom';
|
||||
import _ from 'lodash';
|
||||
import Charts from './Charts';
|
||||
import Clock from './Clock';
|
||||
@@ -55,11 +54,9 @@ class App extends PureComponent {
|
||||
return;
|
||||
}
|
||||
if (this.state.strategy !== 'async') {
|
||||
flushSync(() => {
|
||||
this.setState(state => ({
|
||||
showDemo: !state.showDemo,
|
||||
}));
|
||||
});
|
||||
this.setState(state => ({
|
||||
showDemo: !state.showDemo,
|
||||
}));
|
||||
return;
|
||||
}
|
||||
if (this._ignoreClick) {
|
||||
@@ -67,7 +64,7 @@ class App extends PureComponent {
|
||||
}
|
||||
this._ignoreClick = true;
|
||||
|
||||
Scheduler.unstable_next(() => {
|
||||
unstable_startTransition(() => {
|
||||
this.setState({showDemo: true}, () => {
|
||||
this._ignoreClick = false;
|
||||
});
|
||||
@@ -76,9 +73,7 @@ class App extends PureComponent {
|
||||
|
||||
debouncedHandleChange = _.debounce(value => {
|
||||
if (this.state.strategy === 'debounced') {
|
||||
flushSync(() => {
|
||||
this.setState({value: value});
|
||||
});
|
||||
this.setState({value: value});
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
@@ -108,9 +103,9 @@ class App extends PureComponent {
|
||||
break;
|
||||
case 'async':
|
||||
// TODO: useTransition hook instead.
|
||||
setTimeout(() => {
|
||||
unstable_startTransition(() => {
|
||||
this.setState({value});
|
||||
}, 0);
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
1
fixtures/devtools/scheduling-profiler/.gitignore
vendored
Normal file
1
fixtures/devtools/scheduling-profiler/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
dependencies
|
||||
15
fixtures/devtools/scheduling-profiler/README.md
Normal file
15
fixtures/devtools/scheduling-profiler/README.md
Normal file
@@ -0,0 +1,15 @@
|
||||
# Test fixture for `packages/react-devtools-scheduling-profiler`
|
||||
|
||||
1. First, run the fixture:
|
||||
```sh
|
||||
# In the root directory
|
||||
# Download the latest *experimental* React build
|
||||
scripts/release/download-experimental-build.js
|
||||
|
||||
# Run this fixtures
|
||||
fixtures/devtools/scheduling-profiler/run.js
|
||||
```
|
||||
|
||||
2. Then open [localhost:8000/](http://localhost:8000/) and use the Performance tab in Chrome to reload-and-profile.
|
||||
3. Now stop profiling and export JSON.
|
||||
4. Lastly, open [react-scheduling-profiler.vercel.app](https://react-scheduling-profiler.vercel.app/) and upload the performance JSON data you just recorded.
|
||||
14
fixtures/devtools/scheduling-profiler/app.js
Normal file
14
fixtures/devtools/scheduling-profiler/app.js
Normal file
@@ -0,0 +1,14 @@
|
||||
const {createElement, useLayoutEffect, useState} = React;
|
||||
const {createRoot} = ReactDOM;
|
||||
|
||||
function App() {
|
||||
const [isMounted, setIsMounted] = useState(false);
|
||||
useLayoutEffect(() => {
|
||||
setIsMounted(true);
|
||||
}, []);
|
||||
return createElement('div', null, `isMounted? ${isMounted}`);
|
||||
}
|
||||
|
||||
const container = document.getElementById('container');
|
||||
const root = createRoot(container);
|
||||
root.render(createElement(App));
|
||||
14
fixtures/devtools/scheduling-profiler/index.html
Normal file
14
fixtures/devtools/scheduling-profiler/index.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Scheduling Profiler Fixture</title>
|
||||
|
||||
<script src="./scheduler.js"></script>
|
||||
<script src="./react.js"></script>
|
||||
<script src="./react-dom.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container"></div>
|
||||
<script src="./app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
78
fixtures/devtools/scheduling-profiler/run.js
Executable file
78
fixtures/devtools/scheduling-profiler/run.js
Executable file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
copyFileSync,
|
||||
existsSync,
|
||||
mkdirSync,
|
||||
readFileSync,
|
||||
rmdirSync,
|
||||
} = require('fs');
|
||||
const {join} = require('path');
|
||||
const http = require('http');
|
||||
|
||||
const DEPENDENCIES = [
|
||||
['scheduler/umd/scheduler.development.js', 'scheduler.js'],
|
||||
['react/umd/react.development.js', 'react.js'],
|
||||
['react-dom/umd/react-dom.development.js', 'react-dom.js'],
|
||||
];
|
||||
|
||||
const BUILD_DIRECTORY = '../../../build/node_modules/';
|
||||
const DEPENDENCIES_DIRECTORY = 'dependencies';
|
||||
|
||||
function initDependencies() {
|
||||
if (existsSync(DEPENDENCIES_DIRECTORY)) {
|
||||
rmdirSync(DEPENDENCIES_DIRECTORY, {recursive: true});
|
||||
}
|
||||
mkdirSync(DEPENDENCIES_DIRECTORY);
|
||||
|
||||
DEPENDENCIES.forEach(([from, to]) => {
|
||||
const fromPath = join(__dirname, BUILD_DIRECTORY, from);
|
||||
const toPath = join(__dirname, DEPENDENCIES_DIRECTORY, to);
|
||||
console.log(`Copying ${fromPath} => ${toPath}`);
|
||||
copyFileSync(fromPath, toPath);
|
||||
});
|
||||
}
|
||||
|
||||
function initServer() {
|
||||
const host = 'localhost';
|
||||
const port = 8000;
|
||||
|
||||
const requestListener = function(request, response) {
|
||||
let contents;
|
||||
switch (request.url) {
|
||||
case '/react.js':
|
||||
case '/react-dom.js':
|
||||
case '/scheduler.js':
|
||||
response.setHeader('Content-Type', 'text/javascript');
|
||||
response.writeHead(200);
|
||||
contents = readFileSync(
|
||||
join(__dirname, DEPENDENCIES_DIRECTORY, request.url)
|
||||
);
|
||||
response.end(contents);
|
||||
break;
|
||||
case '/app.js':
|
||||
response.setHeader('Content-Type', 'text/javascript');
|
||||
response.writeHead(200);
|
||||
contents = readFileSync(join(__dirname, 'app.js'));
|
||||
response.end(contents);
|
||||
break;
|
||||
case '/index.html':
|
||||
default:
|
||||
response.setHeader('Content-Type', 'text/html');
|
||||
response.writeHead(200);
|
||||
contents = readFileSync(join(__dirname, 'index.html'));
|
||||
response.end(contents);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const server = http.createServer(requestListener);
|
||||
server.listen(port, host, () => {
|
||||
console.log(`Server is running on http://${host}:${port}`);
|
||||
});
|
||||
}
|
||||
|
||||
initDependencies();
|
||||
initServer();
|
||||
@@ -48,7 +48,7 @@ describe('unmocked scheduler', () => {
|
||||
TestAct(() => {
|
||||
TestRenderer.create(<Effecty />);
|
||||
});
|
||||
expect(log).toEqual(['called']);
|
||||
expect(log).toEqual([]);
|
||||
});
|
||||
expect(log).toEqual(['called']);
|
||||
});
|
||||
|
||||
@@ -1,201 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails react-core
|
||||
*/
|
||||
|
||||
let React;
|
||||
let ReactDOM;
|
||||
let ReactART;
|
||||
let TestUtils;
|
||||
let ARTSVGMode;
|
||||
let ARTCurrentMode;
|
||||
let TestRenderer;
|
||||
let ARTTest;
|
||||
|
||||
global.__DEV__ = process.env.NODE_ENV !== 'production';
|
||||
global.__EXPERIMENTAL__ = process.env.RELEASE_CHANNEL === 'experimental';
|
||||
|
||||
expect.extend(require('../toWarnDev'));
|
||||
|
||||
function App(props) {
|
||||
return 'hello world';
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
React = require('react');
|
||||
ReactDOM = require('react-dom');
|
||||
TestUtils = require('react-dom/test-utils');
|
||||
ReactART = require('react-art');
|
||||
ARTSVGMode = require('art/modes/svg');
|
||||
ARTCurrentMode = require('art/modes/current');
|
||||
TestRenderer = require('react-test-renderer');
|
||||
|
||||
ARTCurrentMode.setCurrent(ARTSVGMode);
|
||||
|
||||
ARTTest = function ARTTestComponent(props) {
|
||||
return (
|
||||
<ReactART.Surface width={150} height={200}>
|
||||
<ReactART.Group>
|
||||
<ReactART.Shape
|
||||
d="M0,0l50,0l0,50l-50,0z"
|
||||
fill={new ReactART.LinearGradient(['black', 'white'])}
|
||||
key="a"
|
||||
width={50}
|
||||
height={50}
|
||||
x={50}
|
||||
y={50}
|
||||
opacity={0.1}
|
||||
/>
|
||||
<ReactART.Shape
|
||||
fill="#3C5A99"
|
||||
key="b"
|
||||
scale={0.5}
|
||||
x={50}
|
||||
y={50}
|
||||
title="This is an F"
|
||||
cursor="pointer">
|
||||
M64.564,38.583H54l0.008-5.834c0-3.035,0.293-4.666,4.657-4.666
|
||||
h5.833V16.429h-9.33c-11.213,0-15.159,5.654-15.159,15.16v6.994
|
||||
h-6.99v11.652h6.99v33.815H54V50.235h9.331L64.564,38.583z
|
||||
</ReactART.Shape>
|
||||
</ReactART.Group>
|
||||
</ReactART.Surface>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
it("doesn't warn when you use the right act + renderer: dom", () => {
|
||||
TestUtils.act(() => {
|
||||
ReactDOM.render(<App />, document.createElement('div'));
|
||||
});
|
||||
});
|
||||
|
||||
it("doesn't warn when you use the right act + renderer: test", () => {
|
||||
TestRenderer.act(() => {
|
||||
TestRenderer.create(<App />);
|
||||
});
|
||||
});
|
||||
|
||||
it('resets correctly across renderers', () => {
|
||||
function Effecty() {
|
||||
React.useEffect(() => {}, []);
|
||||
return null;
|
||||
}
|
||||
TestUtils.act(() => {
|
||||
TestRenderer.act(() => {});
|
||||
expect(() => {
|
||||
TestRenderer.create(<Effecty />);
|
||||
}).toWarnDev(["It looks like you're using the wrong act()"], {
|
||||
withoutStack: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('warns when using the wrong act version - test + dom: render', () => {
|
||||
expect(() => {
|
||||
TestRenderer.act(() => {
|
||||
ReactDOM.render(<App />, document.createElement('div'));
|
||||
});
|
||||
}).toWarnDev(["It looks like you're using the wrong act()"], {
|
||||
withoutStack: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('warns when using the wrong act version - test + dom: updates', () => {
|
||||
let setCtr;
|
||||
function Counter(props) {
|
||||
const [ctr, _setCtr] = React.useState(0);
|
||||
setCtr = _setCtr;
|
||||
return ctr;
|
||||
}
|
||||
ReactDOM.render(<Counter />, document.createElement('div'));
|
||||
expect(() => {
|
||||
TestRenderer.act(() => {
|
||||
setCtr(1);
|
||||
});
|
||||
}).toWarnDev(["It looks like you're using the wrong act()"], {
|
||||
withoutStack: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('warns when using the wrong act version - dom + test: .create()', () => {
|
||||
expect(() => {
|
||||
TestUtils.act(() => {
|
||||
TestRenderer.create(<App />);
|
||||
});
|
||||
}).toWarnDev(["It looks like you're using the wrong act()"], {
|
||||
withoutStack: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('warns when using the wrong act version - dom + test: .update()', () => {
|
||||
const root = TestRenderer.create(<App key="one" />);
|
||||
expect(() => {
|
||||
TestUtils.act(() => {
|
||||
root.update(<App key="two" />);
|
||||
});
|
||||
}).toWarnDev(["It looks like you're using the wrong act()"], {
|
||||
withoutStack: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('warns when using the wrong act version - dom + test: updates', () => {
|
||||
let setCtr;
|
||||
function Counter(props) {
|
||||
const [ctr, _setCtr] = React.useState(0);
|
||||
setCtr = _setCtr;
|
||||
return ctr;
|
||||
}
|
||||
TestRenderer.create(<Counter />);
|
||||
expect(() => {
|
||||
TestUtils.act(() => {
|
||||
setCtr(1);
|
||||
});
|
||||
}).toWarnDev(["It looks like you're using the wrong act()"], {
|
||||
withoutStack: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('does not warn when nesting react-act inside react-dom', () => {
|
||||
TestUtils.act(() => {
|
||||
ReactDOM.render(<ARTTest />, document.createElement('div'));
|
||||
});
|
||||
});
|
||||
|
||||
it('does not warn when nesting react-act inside react-test-renderer', () => {
|
||||
TestRenderer.act(() => {
|
||||
TestRenderer.create(<ARTTest />);
|
||||
});
|
||||
});
|
||||
|
||||
it("doesn't warn if you use nested acts from different renderers", () => {
|
||||
TestRenderer.act(() => {
|
||||
TestUtils.act(() => {
|
||||
TestRenderer.create(<App />);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
if (__EXPERIMENTAL__) {
|
||||
it('warns when using createRoot() + .render', () => {
|
||||
const root = ReactDOM.unstable_createRoot(document.createElement('div'));
|
||||
expect(() => {
|
||||
TestRenderer.act(() => {
|
||||
root.render(<App />);
|
||||
});
|
||||
}).toWarnDev(
|
||||
[
|
||||
'In Concurrent or Sync modes, the "scheduler" module needs to be mocked',
|
||||
"It looks like you're using the wrong act()",
|
||||
],
|
||||
{
|
||||
withoutStack: true,
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -241,6 +241,20 @@ class TrySilenceFatalError extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
function naiveMemoize(fn) {
|
||||
let memoizedEntry;
|
||||
return function() {
|
||||
if (!memoizedEntry) {
|
||||
memoizedEntry = {result: null};
|
||||
memoizedEntry.result = fn();
|
||||
}
|
||||
return memoizedEntry.result;
|
||||
};
|
||||
}
|
||||
let memoizedFunction = naiveMemoize(function() {
|
||||
throw new Error('Passed');
|
||||
});
|
||||
|
||||
export default class ErrorHandlingTestCases extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
@@ -288,6 +302,21 @@ export default class ErrorHandlingTestCases extends React.Component {
|
||||
}}
|
||||
/>
|
||||
</TestCase>
|
||||
<TestCase title="Throwing memoized result" description="">
|
||||
<TestCase.Steps>
|
||||
<li>Click the "Trigger error" button</li>
|
||||
<li>Click the reset button</li>
|
||||
</TestCase.Steps>
|
||||
<TestCase.ExpectedResult>
|
||||
The "Trigger error" button should be replaced with "Captured an
|
||||
error: Passed". Clicking reset should reset the test case.
|
||||
</TestCase.ExpectedResult>
|
||||
<Example
|
||||
doThrow={() => {
|
||||
memoizedFunction().value;
|
||||
}}
|
||||
/>
|
||||
</TestCase>
|
||||
<TestCase
|
||||
title="Cross-origin errors (development mode only)"
|
||||
description="">
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,10 +17,18 @@
|
||||
</p>
|
||||
</div>
|
||||
<script src="../../build/node_modules/react/umd/react.development.js"></script>
|
||||
<script src="../../build/node_modules/react-dom/umd/react-dom-unstable-fizz.browser.development.js"></script>
|
||||
<script src="../../build/node_modules/react-dom/umd/react-dom-server.browser.development.js"></script>
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
|
||||
<script type="text/babel">
|
||||
let stream = ReactDOMFizzServer.renderToReadableStream(<body>Success</body>);
|
||||
let controller = new AbortController();
|
||||
let stream = ReactDOMServer.renderToReadableStream(
|
||||
<html>
|
||||
<body>Success</body>
|
||||
</html>,
|
||||
{
|
||||
signal: controller.signal,
|
||||
}
|
||||
);
|
||||
let response = new Response(stream, {
|
||||
headers: {'Content-Type': 'text/html'},
|
||||
});
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
<script src="../../build/node_modules/react/umd/react.development.js"></script>
|
||||
<script src="../../build/node_modules/react-dom/umd/react-dom.development.js"></script>
|
||||
<script src="../../build/node_modules/react-dom/umd/react-dom-server.browser.development.js"></script>
|
||||
<script src="../../build/node_modules/react-transport-dom-webpack/umd/react-transport-dom-webpack-server.browser.development.js"></script>
|
||||
<script src="../../build/node_modules/react-transport-dom-webpack/umd/react-transport-dom-webpack.development.js"></script>
|
||||
<script src="../../build/node_modules/react-server-dom-webpack/umd/react-server-dom-webpack-writer.browser.development.server.js"></script>
|
||||
<script src="../../build/node_modules/react-server-dom-webpack/umd/react-server-dom-webpack.development.js"></script>
|
||||
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script>
|
||||
<script type="text/babel">
|
||||
let Suspense = React.Suspense;
|
||||
@@ -60,7 +60,7 @@
|
||||
content: <HTML />,
|
||||
};
|
||||
|
||||
let stream = ReactTransportDOMServer.renderToReadableStream(model);
|
||||
let stream = ReactServerDOMWriter.renderToReadableStream(model);
|
||||
let response = new Response(stream, {
|
||||
headers: {'Content-Type': 'text/html'},
|
||||
});
|
||||
@@ -70,13 +70,13 @@
|
||||
let blob = await responseToDisplay.blob();
|
||||
let url = URL.createObjectURL(blob);
|
||||
|
||||
let data = ReactTransportDOMClient.createFromFetch(
|
||||
let data = ReactServerDOMReader.createFromFetch(
|
||||
fetch(url)
|
||||
);
|
||||
// The client also supports XHR streaming.
|
||||
// var xhr = new XMLHttpRequest();
|
||||
// xhr.open('GET', url);
|
||||
// let data = ReactTransportDOMClient.createFromXHR(xhr);
|
||||
// let data = ReactServerDOMReader.createFromXHR(xhr);
|
||||
// xhr.send();
|
||||
|
||||
renderResult(data);
|
||||
|
||||
2
fixtures/flight/.gitignore
vendored
2
fixtures/flight/.gitignore
vendored
@@ -10,6 +10,8 @@
|
||||
|
||||
# production
|
||||
/build
|
||||
/dist
|
||||
.eslintcache
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
|
||||
@@ -17,11 +17,11 @@ if (!NODE_ENV) {
|
||||
// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
|
||||
const dotenvFiles = [
|
||||
`${paths.dotenv}.${NODE_ENV}.local`,
|
||||
`${paths.dotenv}.${NODE_ENV}`,
|
||||
// Don't include `.env.local` for `test` environment
|
||||
// since normally you expect tests to produce the same
|
||||
// results for everyone
|
||||
NODE_ENV !== 'test' && `${paths.dotenv}.local`,
|
||||
`${paths.dotenv}.${NODE_ENV}`,
|
||||
paths.dotenv,
|
||||
].filter(Boolean);
|
||||
|
||||
@@ -46,7 +46,7 @@ dotenvFiles.forEach(dotenvFile => {
|
||||
// It works similar to `NODE_PATH` in Node itself:
|
||||
// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
|
||||
// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
|
||||
// Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
|
||||
// Otherwise, we risk importing Node.js core modules into an app instead of webpack shims.
|
||||
// https://github.com/facebook/create-react-app/issues/1023#issuecomment-265344421
|
||||
// We also resolve them to make sure all tools using them work consistently.
|
||||
const appDirectory = fs.realpathSync(process.cwd());
|
||||
@@ -57,7 +57,7 @@ process.env.NODE_PATH = (process.env.NODE_PATH || '')
|
||||
.join(path.delimiter);
|
||||
|
||||
// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
|
||||
// injected into the application via DefinePlugin in Webpack configuration.
|
||||
// injected into the application via DefinePlugin in webpack configuration.
|
||||
const REACT_APP = /^REACT_APP_/i;
|
||||
|
||||
function getClientEnvironment(publicUrl) {
|
||||
@@ -77,9 +77,22 @@ function getClientEnvironment(publicUrl) {
|
||||
// This should only be used as an escape hatch. Normally you would put
|
||||
// images into the `src` and `import` them in code to get their paths.
|
||||
PUBLIC_URL: publicUrl,
|
||||
// We support configuring the sockjs pathname during development.
|
||||
// These settings let a developer run multiple simultaneous projects.
|
||||
// They are used as the connection `hostname`, `pathname` and `port`
|
||||
// in webpackHotDevClient. They are used as the `sockHost`, `sockPath`
|
||||
// and `sockPort` options in webpack-dev-server.
|
||||
WDS_SOCKET_HOST: process.env.WDS_SOCKET_HOST,
|
||||
WDS_SOCKET_PATH: process.env.WDS_SOCKET_PATH,
|
||||
WDS_SOCKET_PORT: process.env.WDS_SOCKET_PORT,
|
||||
// Whether or not react-refresh is enabled.
|
||||
// react-refresh is not 100% stable at this time,
|
||||
// which is why it's disabled by default.
|
||||
// It is defined here so it is available in the webpackHotDevClient.
|
||||
FAST_REFRESH: process.env.FAST_REFRESH !== 'false',
|
||||
}
|
||||
);
|
||||
// Stringify all values so we can feed into Webpack DefinePlugin
|
||||
// Stringify all values so we can feed into webpack DefinePlugin
|
||||
const stringified = {
|
||||
'process.env': Object.keys(raw).reduce((env, key) => {
|
||||
env[key] = JSON.stringify(raw[key]);
|
||||
|
||||
66
fixtures/flight/config/getHttpsConfig.js
Normal file
66
fixtures/flight/config/getHttpsConfig.js
Normal file
@@ -0,0 +1,66 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const crypto = require('crypto');
|
||||
const chalk = require('react-dev-utils/chalk');
|
||||
const paths = require('./paths');
|
||||
|
||||
// Ensure the certificate and key provided are valid and if not
|
||||
// throw an easy to debug error
|
||||
function validateKeyAndCerts({cert, key, keyFile, crtFile}) {
|
||||
let encrypted;
|
||||
try {
|
||||
// publicEncrypt will throw an error with an invalid cert
|
||||
encrypted = crypto.publicEncrypt(cert, Buffer.from('test'));
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`The certificate "${chalk.yellow(crtFile)}" is invalid.\n${err.message}`
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
// privateDecrypt will throw an error with an invalid key
|
||||
crypto.privateDecrypt(key, encrypted);
|
||||
} catch (err) {
|
||||
throw new Error(
|
||||
`The certificate key "${chalk.yellow(keyFile)}" is invalid.\n${
|
||||
err.message
|
||||
}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Read file and throw an error if it doesn't exist
|
||||
function readEnvFile(file, type) {
|
||||
if (!fs.existsSync(file)) {
|
||||
throw new Error(
|
||||
`You specified ${chalk.cyan(
|
||||
type
|
||||
)} in your env, but the file "${chalk.yellow(file)}" can't be found.`
|
||||
);
|
||||
}
|
||||
return fs.readFileSync(file);
|
||||
}
|
||||
|
||||
// Get the https config
|
||||
// Return cert files if provided in env, otherwise just true or false
|
||||
function getHttpsConfig() {
|
||||
const {SSL_CRT_FILE, SSL_KEY_FILE, HTTPS} = process.env;
|
||||
const isHttps = HTTPS === 'true';
|
||||
|
||||
if (isHttps && SSL_CRT_FILE && SSL_KEY_FILE) {
|
||||
const crtFile = path.resolve(paths.appPath, SSL_CRT_FILE);
|
||||
const keyFile = path.resolve(paths.appPath, SSL_KEY_FILE);
|
||||
const config = {
|
||||
cert: readEnvFile(crtFile, 'SSL_CRT_FILE'),
|
||||
key: readEnvFile(keyFile, 'SSL_KEY_FILE'),
|
||||
};
|
||||
|
||||
validateKeyAndCerts({...config, keyFile, crtFile});
|
||||
return config;
|
||||
}
|
||||
return isHttps;
|
||||
}
|
||||
|
||||
module.exports = getHttpsConfig;
|
||||
@@ -14,15 +14,8 @@ const resolve = require('resolve');
|
||||
function getAdditionalModulePaths(options = {}) {
|
||||
const baseUrl = options.baseUrl;
|
||||
|
||||
// We need to explicitly check for null and undefined (and not a falsy value) because
|
||||
// TypeScript treats an empty string as `.`.
|
||||
if (baseUrl == null) {
|
||||
// If there's no baseUrl set we respect NODE_PATH
|
||||
// Note that NODE_PATH is deprecated and will be removed
|
||||
// in the next major release of create-react-app.
|
||||
|
||||
const nodePath = process.env.NODE_PATH || '';
|
||||
return nodePath.split(path.delimiter).filter(Boolean);
|
||||
if (!baseUrl) {
|
||||
return '';
|
||||
}
|
||||
|
||||
const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
|
||||
@@ -93,7 +86,7 @@ function getJestAliases(options = {}) {
|
||||
|
||||
if (path.relative(paths.appPath, baseUrlResolved) === '') {
|
||||
return {
|
||||
'src/(.*)$': '<rootDir>/src/$1',
|
||||
'^src/(.*)$': '<rootDir>/src/$1',
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
3
fixtures/flight/config/package.json
Normal file
3
fixtures/flight/config/package.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
@@ -2,41 +2,24 @@
|
||||
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const url = require('url');
|
||||
const getPublicUrlOrPath = require('react-dev-utils/getPublicUrlOrPath');
|
||||
|
||||
// Make sure any symlinks in the project folder are resolved:
|
||||
// https://github.com/facebook/create-react-app/issues/637
|
||||
const appDirectory = fs.realpathSync(process.cwd());
|
||||
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
|
||||
|
||||
const envPublicUrl = process.env.PUBLIC_URL;
|
||||
|
||||
function ensureSlash(inputPath, needsSlash) {
|
||||
const hasSlash = inputPath.endsWith('/');
|
||||
if (hasSlash && !needsSlash) {
|
||||
return inputPath.substr(0, inputPath.length - 1);
|
||||
} else if (!hasSlash && needsSlash) {
|
||||
return `${inputPath}/`;
|
||||
} else {
|
||||
return inputPath;
|
||||
}
|
||||
}
|
||||
|
||||
const getPublicUrl = appPackageJson =>
|
||||
envPublicUrl || require(appPackageJson).homepage;
|
||||
|
||||
// We use `PUBLIC_URL` environment variable or "homepage" field to infer
|
||||
// "public path" at which the app is served.
|
||||
// Webpack needs to know it to put the right <script> hrefs into HTML even in
|
||||
// webpack needs to know it to put the right <script> hrefs into HTML even in
|
||||
// single-page apps that may serve index.html for nested URLs like /todos/42.
|
||||
// We can't use a relative path in HTML because we don't want to load something
|
||||
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
|
||||
function getServedPath(appPackageJson) {
|
||||
const publicUrl = getPublicUrl(appPackageJson);
|
||||
const servedUrl =
|
||||
envPublicUrl || (publicUrl ? url.parse(publicUrl).pathname : '/');
|
||||
return ensureSlash(servedUrl, true);
|
||||
}
|
||||
const publicUrlOrPath = getPublicUrlOrPath(
|
||||
process.env.NODE_ENV === 'development',
|
||||
require(resolveApp('package.json')).homepage,
|
||||
process.env.PUBLIC_URL
|
||||
);
|
||||
|
||||
const moduleFileExtensions = [
|
||||
'web.mjs',
|
||||
@@ -81,8 +64,8 @@ module.exports = {
|
||||
testsSetup: resolveModule(resolveApp, 'src/setupTests'),
|
||||
proxySetup: resolveApp('src/setupProxy.js'),
|
||||
appNodeModules: resolveApp('node_modules'),
|
||||
publicUrl: getPublicUrl(resolveApp('package.json')),
|
||||
servedPath: getServedPath(resolveApp('package.json')),
|
||||
swSrc: resolveModule(resolveApp, 'src/service-worker'),
|
||||
publicUrlOrPath,
|
||||
};
|
||||
|
||||
module.exports.moduleFileExtensions = moduleFileExtensions;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
// Fork Start
|
||||
const ReactFlightWebpackPlugin = require('react-transport-dom-webpack/plugin');
|
||||
const ReactFlightWebpackPlugin = require('react-server-dom-webpack/plugin');
|
||||
// Fork End
|
||||
|
||||
const fs = require('fs');
|
||||
const isWsl = require('is-wsl');
|
||||
const path = require('path');
|
||||
const webpack = require('webpack');
|
||||
const resolve = require('resolve');
|
||||
@@ -23,13 +22,14 @@ const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
|
||||
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
|
||||
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
|
||||
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
|
||||
const ESLintPlugin = require('eslint-webpack-plugin');
|
||||
const paths = require('./paths');
|
||||
const modules = require('./modules');
|
||||
const getClientEnvironment = require('./env');
|
||||
const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
|
||||
const ForkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin');
|
||||
const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
|
||||
const eslint = require('eslint');
|
||||
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
|
||||
|
||||
const postcssNormalize = require('postcss-normalize');
|
||||
|
||||
@@ -37,6 +37,14 @@ const appPackageJson = require(paths.appPackageJson);
|
||||
|
||||
// Source maps are resource heavy and can cause out of memory issue for large source files.
|
||||
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
|
||||
|
||||
const webpackDevClientEntry = require.resolve(
|
||||
'react-dev-utils/webpackHotDevClient'
|
||||
);
|
||||
const reactRefreshOverlayEntry = require.resolve(
|
||||
'react-dev-utils/refreshOverlayInterop'
|
||||
);
|
||||
|
||||
// Some apps do not need the benefits of saving a web request, so not inlining the chunk
|
||||
// makes for a smoother build process.
|
||||
const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';
|
||||
@@ -48,12 +56,28 @@ const imageInlineSizeLimit = parseInt(
|
||||
// Check if TypeScript is setup
|
||||
const useTypeScript = fs.existsSync(paths.appTsConfig);
|
||||
|
||||
// Get the path to the uncompiled service worker (if it exists).
|
||||
const swSrc = paths.swSrc;
|
||||
|
||||
// style files regexes
|
||||
const cssRegex = /\.css$/;
|
||||
const cssModuleRegex = /\.module\.css$/;
|
||||
const sassRegex = /\.(scss|sass)$/;
|
||||
const sassModuleRegex = /\.module\.(scss|sass)$/;
|
||||
|
||||
const hasJsxRuntime = (() => {
|
||||
if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
require.resolve('react/jsx-runtime');
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
})();
|
||||
|
||||
// This is the production and development configuration.
|
||||
// It is focused on developer experience, fast rebuilds, and a minimal bundle.
|
||||
module.exports = function(webpackEnv) {
|
||||
@@ -65,24 +89,13 @@ module.exports = function(webpackEnv) {
|
||||
const isEnvProductionProfile =
|
||||
isEnvProduction && process.argv.includes('--profile');
|
||||
|
||||
// Webpack uses `publicPath` to determine where the app is being served from.
|
||||
// It requires a trailing slash, or the file assets will get an incorrect path.
|
||||
// In development, we always serve from the root. This makes config easier.
|
||||
const publicPath = isEnvProduction
|
||||
? paths.servedPath
|
||||
: isEnvDevelopment && '/';
|
||||
// Some apps do not use client-side routing with pushState.
|
||||
// For these, "homepage" can be set to "." to enable relative asset paths.
|
||||
const shouldUseRelativeAssetPaths = publicPath === './';
|
||||
|
||||
// `publicUrl` is just like `publicPath`, but we will provide it to our app
|
||||
// We will provide `paths.publicUrlOrPath` to our app
|
||||
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
|
||||
// Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
|
||||
const publicUrl = isEnvProduction
|
||||
? publicPath.slice(0, -1)
|
||||
: isEnvDevelopment && '';
|
||||
// Get environment variables to inject into our app.
|
||||
const env = getClientEnvironment(publicUrl);
|
||||
const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1));
|
||||
|
||||
const shouldUseReactRefresh = env.raw.FAST_REFRESH;
|
||||
|
||||
// common function to get style loaders
|
||||
const getStyleLoaders = (cssOptions, preProcessor) => {
|
||||
@@ -90,7 +103,11 @@ module.exports = function(webpackEnv) {
|
||||
isEnvDevelopment && require.resolve('style-loader'),
|
||||
isEnvProduction && {
|
||||
loader: MiniCssExtractPlugin.loader,
|
||||
options: shouldUseRelativeAssetPaths ? {publicPath: '../../'} : {},
|
||||
// css is located in `static/css`, use '../../' to locate index.html folder
|
||||
// in production `paths.publicUrlOrPath` can be a relative path
|
||||
options: paths.publicUrlOrPath.startsWith('.')
|
||||
? {publicPath: '../../'}
|
||||
: {},
|
||||
},
|
||||
{
|
||||
loader: require.resolve('css-loader'),
|
||||
@@ -118,7 +135,7 @@ module.exports = function(webpackEnv) {
|
||||
// which in turn let's users customize the target behavior as per their needs.
|
||||
postcssNormalize(),
|
||||
],
|
||||
sourceMap: isEnvProduction && shouldUseSourceMap,
|
||||
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
|
||||
},
|
||||
},
|
||||
].filter(Boolean);
|
||||
@@ -127,7 +144,8 @@ module.exports = function(webpackEnv) {
|
||||
{
|
||||
loader: require.resolve('resolve-url-loader'),
|
||||
options: {
|
||||
sourceMap: isEnvProduction && shouldUseSourceMap,
|
||||
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
|
||||
root: paths.appSrc,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -152,25 +170,31 @@ module.exports = function(webpackEnv) {
|
||||
: isEnvDevelopment && 'cheap-module-source-map',
|
||||
// These are the "entry points" to our application.
|
||||
// This means they will be the "root" imports that are included in JS bundle.
|
||||
entry: [
|
||||
// Include an alternative client for WebpackDevServer. A client's job is to
|
||||
// connect to WebpackDevServer by a socket and get notified about changes.
|
||||
// When you save a file, the client will either apply hot updates (in case
|
||||
// of CSS changes), or refresh the page (in case of JS changes). When you
|
||||
// make a syntax error, this client will display a syntax error overlay.
|
||||
// Note: instead of the default WebpackDevServer client, we use a custom one
|
||||
// to bring better experience for Create React App users. You can replace
|
||||
// the line below with these two lines if you prefer the stock client:
|
||||
// require.resolve('webpack-dev-server/client') + '?/',
|
||||
// require.resolve('webpack/hot/dev-server'),
|
||||
isEnvDevelopment &&
|
||||
require.resolve('react-dev-utils/webpackHotDevClient'),
|
||||
// Finally, this is your app's code:
|
||||
paths.appIndexJs,
|
||||
// We include the app code last so that if there is a runtime error during
|
||||
// initialization, it doesn't blow up the WebpackDevServer client, and
|
||||
// changing JS code would still trigger a refresh.
|
||||
].filter(Boolean),
|
||||
entry:
|
||||
isEnvDevelopment && !shouldUseReactRefresh
|
||||
? [
|
||||
// Include an alternative client for WebpackDevServer. A client's job is to
|
||||
// connect to WebpackDevServer by a socket and get notified about changes.
|
||||
// When you save a file, the client will either apply hot updates (in case
|
||||
// of CSS changes), or refresh the page (in case of JS changes). When you
|
||||
// make a syntax error, this client will display a syntax error overlay.
|
||||
// Note: instead of the default WebpackDevServer client, we use a custom one
|
||||
// to bring better experience for Create React App users. You can replace
|
||||
// the line below with these two lines if you prefer the stock client:
|
||||
//
|
||||
// require.resolve('webpack-dev-server/client') + '?/',
|
||||
// require.resolve('webpack/hot/dev-server'),
|
||||
//
|
||||
// When using the experimental react-refresh integration,
|
||||
// the webpack plugin takes care of injecting the dev client for us.
|
||||
webpackDevClientEntry,
|
||||
// Finally, this is your app's code:
|
||||
paths.appIndexJs,
|
||||
// We include the app code last so that if there is a runtime error during
|
||||
// initialization, it doesn't blow up the WebpackDevServer client, and
|
||||
// changing JS code would still trigger a refresh.
|
||||
]
|
||||
: paths.appIndexJs,
|
||||
output: {
|
||||
// The build folder.
|
||||
path: isEnvProduction ? paths.appBuild : undefined,
|
||||
@@ -187,9 +211,10 @@ module.exports = function(webpackEnv) {
|
||||
chunkFilename: isEnvProduction
|
||||
? 'static/js/[name].[contenthash:8].chunk.js'
|
||||
: isEnvDevelopment && 'static/js/[name].chunk.js',
|
||||
// webpack uses `publicPath` to determine where the app is being served from.
|
||||
// It requires a trailing slash, or the file assets will get an incorrect path.
|
||||
// We inferred the "public path" (such as / or /my-project) from homepage.
|
||||
// We use "/" in development.
|
||||
publicPath: publicPath,
|
||||
publicPath: paths.publicUrlOrPath,
|
||||
// Point sourcemap entries to original disk location (format as URL on Windows)
|
||||
devtoolModuleFilenameTemplate: isEnvProduction
|
||||
? info =>
|
||||
@@ -198,7 +223,7 @@ module.exports = function(webpackEnv) {
|
||||
.replace(/\\/g, '/')
|
||||
: isEnvDevelopment &&
|
||||
(info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
|
||||
// Prevents conflicts when multiple Webpack runtimes (from different apps)
|
||||
// Prevents conflicts when multiple webpack runtimes (from different apps)
|
||||
// are used on the same page.
|
||||
jsonpFunction: `webpackJsonp${appPackageJson.name}`,
|
||||
// this defaults to 'window', but by setting it to 'this' then
|
||||
@@ -247,13 +272,6 @@ module.exports = function(webpackEnv) {
|
||||
ascii_only: true,
|
||||
},
|
||||
},
|
||||
// Use multi-process parallel running to improve the build speed
|
||||
// Default number of concurrent runs: os.cpus().length - 1
|
||||
// Disabled on WSL (Windows Subsystem for Linux) due to an issue with Terser
|
||||
// https://github.com/webpack-contrib/terser-webpack-plugin/issues/21
|
||||
parallel: !isWsl,
|
||||
// Enable file caching
|
||||
cache: true,
|
||||
sourceMap: shouldUseSourceMap,
|
||||
}),
|
||||
// This is only used in production mode
|
||||
@@ -271,6 +289,9 @@ module.exports = function(webpackEnv) {
|
||||
}
|
||||
: false,
|
||||
},
|
||||
cssProcessorPluginOptions: {
|
||||
preset: ['default', {minifyFontValues: {removeQuotes: false}}],
|
||||
},
|
||||
}),
|
||||
],
|
||||
// Automatically split vendor and commons
|
||||
@@ -288,7 +309,7 @@ module.exports = function(webpackEnv) {
|
||||
},
|
||||
},
|
||||
resolve: {
|
||||
// This allows you to set a fallback for where Webpack should look for modules.
|
||||
// This allows you to set a fallback for where webpack should look for modules.
|
||||
// We placed these paths second because we want `node_modules` to "win"
|
||||
// if there are any conflicts. This matches Node resolution mechanism.
|
||||
// https://github.com/facebook/create-react-app/issues/253
|
||||
@@ -324,12 +345,15 @@ module.exports = function(webpackEnv) {
|
||||
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
|
||||
// please link the files into your node_modules/ and let module-resolution kick in.
|
||||
// Make sure your source files are compiled, as they will not be processed in any way.
|
||||
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
|
||||
new ModuleScopePlugin(paths.appSrc, [
|
||||
paths.appPackageJson,
|
||||
reactRefreshOverlayEntry,
|
||||
]),
|
||||
],
|
||||
},
|
||||
resolveLoader: {
|
||||
plugins: [
|
||||
// Also related to Plug'n'Play, but this time it tells Webpack to load its loaders
|
||||
// Also related to Plug'n'Play, but this time it tells webpack to load its loaders
|
||||
// from the current package.
|
||||
PnpWebpackPlugin.moduleLoader(module),
|
||||
],
|
||||
@@ -339,30 +363,22 @@ module.exports = function(webpackEnv) {
|
||||
rules: [
|
||||
// Disable require.ensure as it's not a standard language feature.
|
||||
{parser: {requireEnsure: false}},
|
||||
|
||||
// First, run the linter.
|
||||
// It's important to do this before Babel processes the JS.
|
||||
{
|
||||
test: /\.(js|mjs|jsx|ts|tsx)$/,
|
||||
enforce: 'pre',
|
||||
use: [
|
||||
{
|
||||
options: {
|
||||
cache: true,
|
||||
formatter: require.resolve('react-dev-utils/eslintFormatter'),
|
||||
eslintPath: require.resolve('eslint'),
|
||||
resolvePluginsRelativeTo: __dirname,
|
||||
},
|
||||
loader: require.resolve('eslint-loader'),
|
||||
},
|
||||
],
|
||||
include: paths.appSrc,
|
||||
},
|
||||
{
|
||||
// "oneOf" will traverse all following loaders until one will
|
||||
// match the requirements. When no loader matches it will fall
|
||||
// back to the "file" loader at the end of the loader list.
|
||||
oneOf: [
|
||||
// TODO: Merge this config once `image/avif` is in the mime-db
|
||||
// https://github.com/jshttp/mime-db
|
||||
{
|
||||
test: [/\.avif$/],
|
||||
loader: require.resolve('url-loader'),
|
||||
options: {
|
||||
limit: imageInlineSizeLimit,
|
||||
mimetype: 'image/avif',
|
||||
name: 'static/media/[name].[hash:8].[ext]',
|
||||
},
|
||||
},
|
||||
// "url" loader works like "file" loader except that it embeds assets
|
||||
// smaller than specified limit in bytes as data URLs to avoid requests.
|
||||
// A missing `test` is equivalent to a match.
|
||||
@@ -384,6 +400,14 @@ module.exports = function(webpackEnv) {
|
||||
customize: require.resolve(
|
||||
'babel-preset-react-app/webpack-overrides'
|
||||
),
|
||||
presets: [
|
||||
[
|
||||
require.resolve('babel-preset-react-app'),
|
||||
{
|
||||
runtime: hasJsxRuntime ? 'automatic' : 'classic',
|
||||
},
|
||||
],
|
||||
],
|
||||
|
||||
plugins: [
|
||||
[
|
||||
@@ -397,7 +421,10 @@ module.exports = function(webpackEnv) {
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
isEnvDevelopment &&
|
||||
shouldUseReactRefresh &&
|
||||
require.resolve('react-refresh/babel'),
|
||||
].filter(Boolean),
|
||||
// This is a feature of `babel-loader` for webpack (not Babel itself).
|
||||
// It enables caching results in ./node_modules/.cache/babel-loader/
|
||||
// directory for faster rebuilds.
|
||||
@@ -427,11 +454,11 @@ module.exports = function(webpackEnv) {
|
||||
// See #6846 for context on why cacheCompression is disabled
|
||||
cacheCompression: false,
|
||||
|
||||
// If an error happens in a package, it's possible to be
|
||||
// because it was compiled. Thus, we don't want the browser
|
||||
// debugger to show the original code. Instead, the code
|
||||
// being evaluated would be much more helpful.
|
||||
sourceMaps: false,
|
||||
// Babel sourcemaps are needed for debugging into node_modules
|
||||
// code. Without the options below, debuggers like VSCode
|
||||
// show incorrect code and set breakpoints on the wrong lines.
|
||||
sourceMaps: shouldUseSourceMap,
|
||||
inputSourceMap: shouldUseSourceMap,
|
||||
},
|
||||
},
|
||||
// "postcss" loader applies autoprefixer to our CSS.
|
||||
@@ -446,7 +473,9 @@ module.exports = function(webpackEnv) {
|
||||
exclude: cssModuleRegex,
|
||||
use: getStyleLoaders({
|
||||
importLoaders: 1,
|
||||
sourceMap: isEnvProduction && shouldUseSourceMap,
|
||||
sourceMap: isEnvProduction
|
||||
? shouldUseSourceMap
|
||||
: isEnvDevelopment,
|
||||
}),
|
||||
// Don't consider CSS imports dead code even if the
|
||||
// containing package claims to have no side effects.
|
||||
@@ -460,9 +489,12 @@ module.exports = function(webpackEnv) {
|
||||
test: cssModuleRegex,
|
||||
use: getStyleLoaders({
|
||||
importLoaders: 1,
|
||||
sourceMap: isEnvProduction && shouldUseSourceMap,
|
||||
modules: true,
|
||||
getLocalIdent: getCSSModuleLocalIdent,
|
||||
sourceMap: isEnvProduction
|
||||
? shouldUseSourceMap
|
||||
: isEnvDevelopment,
|
||||
modules: {
|
||||
getLocalIdent: getCSSModuleLocalIdent,
|
||||
},
|
||||
}),
|
||||
},
|
||||
// Opt-in support for SASS (using .scss or .sass extensions).
|
||||
@@ -473,8 +505,10 @@ module.exports = function(webpackEnv) {
|
||||
exclude: sassModuleRegex,
|
||||
use: getStyleLoaders(
|
||||
{
|
||||
importLoaders: 2,
|
||||
sourceMap: isEnvProduction && shouldUseSourceMap,
|
||||
importLoaders: 3,
|
||||
sourceMap: isEnvProduction
|
||||
? shouldUseSourceMap
|
||||
: isEnvDevelopment,
|
||||
},
|
||||
'sass-loader'
|
||||
),
|
||||
@@ -490,10 +524,13 @@ module.exports = function(webpackEnv) {
|
||||
test: sassModuleRegex,
|
||||
use: getStyleLoaders(
|
||||
{
|
||||
importLoaders: 2,
|
||||
sourceMap: isEnvProduction && shouldUseSourceMap,
|
||||
modules: true,
|
||||
getLocalIdent: getCSSModuleLocalIdent,
|
||||
importLoaders: 3,
|
||||
sourceMap: isEnvProduction
|
||||
? shouldUseSourceMap
|
||||
: isEnvDevelopment,
|
||||
modules: {
|
||||
getLocalIdent: getCSSModuleLocalIdent,
|
||||
},
|
||||
},
|
||||
'sass-loader'
|
||||
),
|
||||
@@ -556,9 +593,8 @@ module.exports = function(webpackEnv) {
|
||||
// Makes some environment variables available in index.html.
|
||||
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
|
||||
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
|
||||
// In production, it will be an empty string unless you specify "homepage"
|
||||
// It will be an empty string unless you specify "homepage"
|
||||
// in `package.json`, in which case it will be the pathname of that URL.
|
||||
// In development, this will be an empty string.
|
||||
new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
|
||||
// This gives some necessary context to module not found errors, such as
|
||||
// the requesting resource.
|
||||
@@ -569,14 +605,29 @@ module.exports = function(webpackEnv) {
|
||||
// during a production build.
|
||||
// Otherwise React will be compiled in the very slow development mode.
|
||||
new webpack.DefinePlugin(env.stringified),
|
||||
// This is necessary to emit hot updates (currently CSS only):
|
||||
// This is necessary to emit hot updates (CSS and Fast Refresh):
|
||||
isEnvDevelopment && new webpack.HotModuleReplacementPlugin(),
|
||||
// Experimental hot reloading for React .
|
||||
// https://github.com/facebook/react/tree/master/packages/react-refresh
|
||||
isEnvDevelopment &&
|
||||
shouldUseReactRefresh &&
|
||||
new ReactRefreshWebpackPlugin({
|
||||
overlay: {
|
||||
entry: webpackDevClientEntry,
|
||||
// The expected exports are slightly different from what the overlay exports,
|
||||
// so an interop is included here to enable feedback on module-level errors.
|
||||
module: reactRefreshOverlayEntry,
|
||||
// Since we ship a custom dev client and overlay integration,
|
||||
// the bundled socket handling logic can be eliminated.
|
||||
sockIntegration: false,
|
||||
},
|
||||
}),
|
||||
// Watcher doesn't work well if you mistype casing in a path so we use
|
||||
// a plugin that prints an error when you attempt to do this.
|
||||
// See https://github.com/facebook/create-react-app/issues/240
|
||||
isEnvDevelopment && new CaseSensitivePathsPlugin(),
|
||||
// If you require a missing module and then `npm install` it, you still have
|
||||
// to restart the development server for Webpack to discover it. This plugin
|
||||
// to restart the development server for webpack to discover it. This plugin
|
||||
// makes the discovery automatic so you don't have to restart.
|
||||
// See https://github.com/facebook/create-react-app/issues/186
|
||||
isEnvDevelopment &&
|
||||
@@ -596,7 +647,7 @@ module.exports = function(webpackEnv) {
|
||||
// can be used to reconstruct the HTML if necessary
|
||||
new ManifestPlugin({
|
||||
fileName: 'asset-manifest.json',
|
||||
publicPath: publicPath,
|
||||
publicPath: paths.publicUrlOrPath,
|
||||
generate: (seed, files, entrypoints) => {
|
||||
const manifestFiles = files.reduce((manifest, file) => {
|
||||
manifest[file.name] = file.path;
|
||||
@@ -613,28 +664,23 @@ module.exports = function(webpackEnv) {
|
||||
},
|
||||
}),
|
||||
// Moment.js is an extremely popular library that bundles large locale files
|
||||
// by default due to how Webpack interprets its code. This is a practical
|
||||
// by default due to how webpack interprets its code. This is a practical
|
||||
// solution that requires the user to opt into importing specific locales.
|
||||
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
|
||||
// You can remove this if you don't use Moment.js:
|
||||
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
||||
// Generate a service worker script that will precache, and keep up to date,
|
||||
// the HTML & assets that are part of the Webpack build.
|
||||
// the HTML & assets that are part of the webpack build.
|
||||
isEnvProduction &&
|
||||
new WorkboxWebpackPlugin.GenerateSW({
|
||||
clientsClaim: true,
|
||||
exclude: [/\.map$/, /asset-manifest\.json$/],
|
||||
importWorkboxFrom: 'cdn',
|
||||
navigateFallback: publicUrl + '/index.html',
|
||||
navigateFallbackBlacklist: [
|
||||
// Exclude URLs starting with /_, as they're likely an API call
|
||||
new RegExp('^/_'),
|
||||
// Exclude any URLs whose last part seems to be a file extension
|
||||
// as they're likely a resource and not a SPA route.
|
||||
// URLs containing a "?" character won't be blacklisted as they're likely
|
||||
// a route with query params (e.g. auth callbacks).
|
||||
new RegExp('/[^/?]+\\.[^/]+$'),
|
||||
],
|
||||
fs.existsSync(swSrc) &&
|
||||
new WorkboxWebpackPlugin.InjectManifest({
|
||||
swSrc,
|
||||
dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./,
|
||||
exclude: [/\.map$/, /asset-manifest\.json$/, /LICENSE/],
|
||||
// Bump up the default maximum size (2mb) that's precached,
|
||||
// to make lazy-loading failure scenarios less likely.
|
||||
// See https://github.com/cra-template/pwa/issues/13#issuecomment-722667270
|
||||
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
|
||||
}),
|
||||
// TypeScript type checking
|
||||
useTypeScript &&
|
||||
@@ -643,7 +689,6 @@ module.exports = function(webpackEnv) {
|
||||
basedir: paths.appNodeModules,
|
||||
}),
|
||||
async: isEnvDevelopment,
|
||||
useTypescriptIncrementalApi: true,
|
||||
checkSyntacticErrors: true,
|
||||
resolveModuleNameModule: process.versions.pnp
|
||||
? `${__dirname}/pnpTs.js`
|
||||
@@ -653,9 +698,14 @@ module.exports = function(webpackEnv) {
|
||||
: undefined,
|
||||
tsconfig: paths.appTsConfig,
|
||||
reportFiles: [
|
||||
'**',
|
||||
'!**/__tests__/**',
|
||||
'!**/?(*.)(spec|test).*',
|
||||
// This one is specifically to match during CI tests,
|
||||
// as micromatch doesn't match
|
||||
// '../cra-template-typescript/template/src/App.tsx'
|
||||
// otherwise.
|
||||
'../**/src/**/*.{ts,tsx}',
|
||||
'**/src/**/*.{ts,tsx}',
|
||||
'!**/src/**/__tests__/**',
|
||||
'!**/src/**/?(*.)(spec|test).*',
|
||||
'!**/src/setupProxy.*',
|
||||
'!**/src/setupTests.*',
|
||||
],
|
||||
@@ -663,12 +713,31 @@ module.exports = function(webpackEnv) {
|
||||
// The formatter is invoked directly in WebpackDevServerUtils during development
|
||||
formatter: isEnvProduction ? typescriptFormatter : undefined,
|
||||
}),
|
||||
new ESLintPlugin({
|
||||
// Plugin options
|
||||
extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'],
|
||||
formatter: require.resolve('react-dev-utils/eslintFormatter'),
|
||||
eslintPath: require.resolve('eslint'),
|
||||
context: paths.appSrc,
|
||||
cache: true,
|
||||
// ESLint class options
|
||||
cwd: paths.appPath,
|
||||
resolvePluginsRelativeTo: __dirname,
|
||||
baseConfig: {
|
||||
extends: [require.resolve('eslint-config-react-app/base')],
|
||||
rules: {
|
||||
...(!hasJsxRuntime && {
|
||||
'react/react-in-jsx-scope': 'error',
|
||||
}),
|
||||
},
|
||||
},
|
||||
}),
|
||||
// Fork Start
|
||||
new ReactFlightWebpackPlugin({isServer: false}),
|
||||
// Fork End
|
||||
].filter(Boolean),
|
||||
// Some libraries import Node modules but don't use them in the browser.
|
||||
// Tell Webpack to provide empty mocks for them so importing them works.
|
||||
// Tell webpack to provide empty mocks for them so importing them works.
|
||||
node: {
|
||||
module: 'empty',
|
||||
dgram: 'empty',
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const errorOverlayMiddleware = require('react-dev-utils/errorOverlayMiddleware');
|
||||
const evalSourceMapMiddleware = require('react-dev-utils/evalSourceMapMiddleware');
|
||||
const noopServiceWorkerMiddleware = require('react-dev-utils/noopServiceWorkerMiddleware');
|
||||
const ignoredFiles = require('react-dev-utils/ignoredFiles');
|
||||
const redirectServedPath = require('react-dev-utils/redirectServedPathMiddleware');
|
||||
const paths = require('./paths');
|
||||
const fs = require('fs');
|
||||
const getHttpsConfig = require('./getHttpsConfig');
|
||||
|
||||
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
|
||||
const host = process.env.HOST || '0.0.0.0';
|
||||
const sockHost = process.env.WDS_SOCKET_HOST;
|
||||
const sockPath = process.env.WDS_SOCKET_PATH; // default: '/sockjs-node'
|
||||
const sockPort = process.env.WDS_SOCKET_PORT;
|
||||
|
||||
module.exports = function(proxy, allowedHost) {
|
||||
return {
|
||||
@@ -47,20 +51,35 @@ module.exports = function(proxy, allowedHost) {
|
||||
// In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
|
||||
// Note that we only recommend to use `public` folder as an escape hatch
|
||||
// for files like `favicon.ico`, `manifest.json`, and libraries that are
|
||||
// for some reason broken when imported through Webpack. If you just want to
|
||||
// for some reason broken when imported through webpack. If you just want to
|
||||
// use an image, put it in `src` and `import` it from JavaScript instead.
|
||||
contentBase: paths.appPublic,
|
||||
contentBasePublicPath: paths.publicUrlOrPath,
|
||||
// By default files from `contentBase` will not trigger a page reload.
|
||||
watchContentBase: true,
|
||||
// Enable hot reloading server. It will provide /sockjs-node/ endpoint
|
||||
// Enable hot reloading server. It will provide WDS_SOCKET_PATH endpoint
|
||||
// for the WebpackDevServer client so it can learn when the files were
|
||||
// updated. The WebpackDevServer client is included as an entry point
|
||||
// in the Webpack development configuration. Note that only changes
|
||||
// in the webpack development configuration. Note that only changes
|
||||
// to CSS are currently hot reloaded. JS changes will refresh the browser.
|
||||
hot: true,
|
||||
// It is important to tell WebpackDevServer to use the same "root" path
|
||||
// as we specified in the config. In development, we always serve from /.
|
||||
publicPath: '/',
|
||||
// Use 'ws' instead of 'sockjs-node' on server since we're using native
|
||||
// websockets in `webpackHotDevClient`.
|
||||
transportMode: 'ws',
|
||||
// Prevent a WS client from getting injected as we're already including
|
||||
// `webpackHotDevClient`.
|
||||
injectClient: false,
|
||||
// Enable custom sockjs pathname for websocket connection to hot reloading server.
|
||||
// Enable custom sockjs hostname, pathname and port for websocket connection
|
||||
// to hot reloading server.
|
||||
sockHost,
|
||||
sockPath,
|
||||
sockPort,
|
||||
// It is important to tell WebpackDevServer to use the same "publicPath" path as
|
||||
// we specified in the webpack config. When homepage is '.', default to serving
|
||||
// from the root.
|
||||
// remove last slash so user can land on `/test` instead of `/test/`
|
||||
publicPath: paths.publicUrlOrPath.slice(0, -1),
|
||||
// WebpackDevServer is noisy by default so we emit custom message instead
|
||||
// by listening to the compiler events with `compiler.hooks[...].tap` calls above.
|
||||
quiet: true,
|
||||
@@ -71,34 +90,44 @@ module.exports = function(proxy, allowedHost) {
|
||||
watchOptions: {
|
||||
ignored: ignoredFiles(paths.appSrc),
|
||||
},
|
||||
// Enable HTTPS if the HTTPS environment variable is set to 'true'
|
||||
https: protocol === 'https',
|
||||
writeToDisk: filePath => {
|
||||
return /react-client-manifest\.json$/.test(filePath);
|
||||
},
|
||||
https: getHttpsConfig(),
|
||||
host,
|
||||
overlay: false,
|
||||
historyApiFallback: {
|
||||
// Paths with dots should still use the history fallback.
|
||||
// See https://github.com/facebook/create-react-app/issues/387.
|
||||
disableDotRule: true,
|
||||
index: paths.publicUrlOrPath,
|
||||
},
|
||||
public: allowedHost,
|
||||
// `proxy` is run between `before` and `after` `webpack-dev-server` hooks
|
||||
proxy,
|
||||
before(app, server) {
|
||||
if (fs.existsSync(paths.proxySetup)) {
|
||||
// This registers user provided middleware for proxy reasons
|
||||
require(paths.proxySetup)(app);
|
||||
}
|
||||
|
||||
// Keep `evalSourceMapMiddleware` and `errorOverlayMiddleware`
|
||||
// middlewares before `redirectServedPath` otherwise will not have any effect
|
||||
// This lets us fetch source contents from webpack for the error overlay
|
||||
app.use(evalSourceMapMiddleware(server));
|
||||
// This lets us open files from the runtime error overlay.
|
||||
app.use(errorOverlayMiddleware());
|
||||
|
||||
if (fs.existsSync(paths.proxySetup)) {
|
||||
// This registers user provided middleware for proxy reasons
|
||||
require(paths.proxySetup)(app);
|
||||
}
|
||||
},
|
||||
after(app) {
|
||||
// Redirect to `PUBLIC_URL` or `homepage` from `package.json` if url not match
|
||||
app.use(redirectServedPath(paths.publicUrlOrPath));
|
||||
|
||||
// This service worker file is effectively a 'no-op' that will reset any
|
||||
// previous service worker registered for the same host:port combination.
|
||||
// We do this in development to avoid hitting the production cache if
|
||||
// it used the same host and port.
|
||||
// https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432
|
||||
app.use(noopServiceWorkerMiddleware());
|
||||
app.use(noopServiceWorkerMiddleware(paths.publicUrlOrPath));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
34
fixtures/flight/loader/index.js
Normal file
34
fixtures/flight/loader/index.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import {
|
||||
resolve,
|
||||
getSource,
|
||||
transformSource as reactTransformSource,
|
||||
} from 'react-server-dom-webpack/node-loader';
|
||||
|
||||
export {resolve, getSource};
|
||||
|
||||
import babel from '@babel/core';
|
||||
|
||||
const babelOptions = {
|
||||
babelrc: false,
|
||||
ignore: [/\/(build|node_modules)\//],
|
||||
plugins: [
|
||||
'@babel/plugin-syntax-import-meta',
|
||||
'@babel/plugin-transform-react-jsx',
|
||||
],
|
||||
};
|
||||
|
||||
async function babelTransformSource(source, context, defaultTransformSource) {
|
||||
const {format} = context;
|
||||
if (format === 'module') {
|
||||
const opt = Object.assign({filename: context.url}, babelOptions);
|
||||
const {code} = await babel.transformAsync(source, opt);
|
||||
return {source: code};
|
||||
}
|
||||
return defaultTransformSource(source, context, defaultTransformSource);
|
||||
}
|
||||
|
||||
export async function transformSource(source, context, defaultTransformSource) {
|
||||
return reactTransformSource(source, context, (s, c) => {
|
||||
return babelTransformSource(s, c, defaultTransformSource);
|
||||
});
|
||||
}
|
||||
3
fixtures/flight/loader/package.json
Normal file
3
fixtures/flight/loader/package.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "module"
|
||||
}
|
||||
@@ -1,72 +1,82 @@
|
||||
{
|
||||
"name": "flight",
|
||||
"type": "module",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@babel/core": "7.6.0",
|
||||
"@babel/core": "7.12.3",
|
||||
"@babel/plugin-syntax-import-meta": "^7.10.4",
|
||||
"@babel/register": "^7.7.0",
|
||||
"@svgr/webpack": "4.3.2",
|
||||
"@typescript-eslint/eslint-plugin": "^2.2.0",
|
||||
"@typescript-eslint/parser": "^2.2.0",
|
||||
"babel-eslint": "10.0.3",
|
||||
"babel-jest": "^24.9.0",
|
||||
"babel-loader": "8.0.6",
|
||||
"babel-plugin-named-asset-import": "^0.3.4",
|
||||
"babel-preset-react-app": "^9.0.2",
|
||||
"camelcase": "^5.2.0",
|
||||
"case-sensitive-paths-webpack-plugin": "2.2.0",
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "0.4.2",
|
||||
"@svgr/webpack": "5.4.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.5.0",
|
||||
"@typescript-eslint/parser": "^4.5.0",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"babel-jest": "^26.6.0",
|
||||
"babel-loader": "8.1.0",
|
||||
"babel-plugin-named-asset-import": "^0.3.7",
|
||||
"babel-preset-react-app": "^10.0.0",
|
||||
"bfj": "^7.0.2",
|
||||
"camelcase": "^6.1.0",
|
||||
"case-sensitive-paths-webpack-plugin": "2.3.0",
|
||||
"concurrently": "^5.0.0",
|
||||
"css-loader": "2.1.1",
|
||||
"dotenv": "6.2.0",
|
||||
"css-loader": "4.3.0",
|
||||
"dotenv": "8.2.0",
|
||||
"dotenv-expand": "5.1.0",
|
||||
"eslint": "^6.1.0",
|
||||
"eslint-config-react-app": "^5.0.2",
|
||||
"eslint-loader": "3.0.2",
|
||||
"eslint-plugin-flowtype": "3.13.0",
|
||||
"eslint-plugin-import": "2.18.2",
|
||||
"eslint-plugin-jsx-a11y": "6.2.3",
|
||||
"eslint-plugin-react": "7.14.3",
|
||||
"eslint-plugin-react-hooks": "^1.6.1",
|
||||
"eslint": "^7.11.0",
|
||||
"eslint-config-react-app": "^6.0.0",
|
||||
"eslint-plugin-flowtype": "^5.2.0",
|
||||
"eslint-plugin-import": "^2.22.1",
|
||||
"eslint-plugin-jest": "^24.1.0",
|
||||
"eslint-plugin-jsx-a11y": "^6.3.1",
|
||||
"eslint-plugin-react": "^7.21.5",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"eslint-plugin-testing-library": "^3.9.2",
|
||||
"eslint-webpack-plugin": "^2.1.0",
|
||||
"express": "^4.17.1",
|
||||
"file-loader": "3.0.1",
|
||||
"fs-extra": "7.0.1",
|
||||
"html-webpack-plugin": "4.0.0-beta.5",
|
||||
"file-loader": "6.1.1",
|
||||
"fs-extra": "^9.0.1",
|
||||
"html-webpack-plugin": "4.5.0",
|
||||
"identity-obj-proxy": "3.0.0",
|
||||
"is-wsl": "^1.1.0",
|
||||
"jest": "24.9.0",
|
||||
"jest-environment-jsdom-fourteen": "0.1.0",
|
||||
"jest-resolve": "24.9.0",
|
||||
"jest-watch-typeahead": "0.4.0",
|
||||
"mini-css-extract-plugin": "0.8.0",
|
||||
"optimize-css-assets-webpack-plugin": "5.0.3",
|
||||
"pnp-webpack-plugin": "1.5.0",
|
||||
"postcss-flexbugs-fixes": "4.1.0",
|
||||
"jest": "26.6.0",
|
||||
"jest-circus": "26.6.0",
|
||||
"jest-resolve": "26.6.0",
|
||||
"jest-watch-typeahead": "0.6.1",
|
||||
"mini-css-extract-plugin": "0.11.3",
|
||||
"nodemon": "^2.0.6",
|
||||
"optimize-css-assets-webpack-plugin": "5.0.4",
|
||||
"pnp-webpack-plugin": "1.6.4",
|
||||
"postcss-flexbugs-fixes": "4.2.1",
|
||||
"postcss-loader": "3.0.0",
|
||||
"postcss-normalize": "7.0.1",
|
||||
"postcss-normalize": "8.0.1",
|
||||
"postcss-preset-env": "6.7.0",
|
||||
"postcss-safe-parser": "4.0.1",
|
||||
"react-app-polyfill": "^1.0.4",
|
||||
"react-dev-utils": "^9.1.0",
|
||||
"resolve": "1.12.0",
|
||||
"resolve-url-loader": "3.1.0",
|
||||
"sass-loader": "7.2.0",
|
||||
"semver": "6.3.0",
|
||||
"style-loader": "1.0.0",
|
||||
"terser-webpack-plugin": "1.4.1",
|
||||
"ts-pnp": "1.1.4",
|
||||
"url-loader": "2.1.0",
|
||||
"webpack": "4.41.0",
|
||||
"webpack-dev-server": "3.2.1",
|
||||
"webpack-manifest-plugin": "2.1.1",
|
||||
"workbox-webpack-plugin": "4.3.1"
|
||||
"postcss-safe-parser": "5.0.2",
|
||||
"prompts": "2.4.0",
|
||||
"react-app-polyfill": "^2.0.0",
|
||||
"react-dev-utils": "^11.0.1",
|
||||
"react-refresh": "^0.8.3",
|
||||
"resolve": "1.18.1",
|
||||
"resolve-url-loader": "^3.1.2",
|
||||
"sass-loader": "8.0.2",
|
||||
"semver": "7.3.2",
|
||||
"style-loader": "1.3.0",
|
||||
"terser-webpack-plugin": "4.2.3",
|
||||
"ts-pnp": "1.2.0",
|
||||
"url-loader": "4.1.1",
|
||||
"webpack": "4.44.2",
|
||||
"webpack-dev-server": "3.11.0",
|
||||
"webpack-manifest-plugin": "2.2.0",
|
||||
"workbox-webpack-plugin": "5.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"prestart": "cp -r ../../build/node_modules/* ./node_modules/",
|
||||
"prebuild": "cp -r ../../build/node_modules/* ./node_modules/",
|
||||
"start": "concurrently \"npm run start:server\" \"npm run start:client\"",
|
||||
"start:client": "node scripts/start.js",
|
||||
"start:server": "NODE_ENV=development node server",
|
||||
"start:prod": "node scripts/build.js && NODE_ENV=production node server",
|
||||
"start:server": "NODE_ENV=development nodemon -- --experimental-loader ./loader/index.js --conditions=react-server server",
|
||||
"start:prod": "node scripts/build.js && concurrently \"npm run start:prod-server\" \"npm run start:prod-client\"",
|
||||
"start:prod-client": "cd ./build && python -m SimpleHTTPServer 3000",
|
||||
"start:prod-server": "NODE_ENV=production node --experimental-loader ./loader/index.js --conditions=react-server server",
|
||||
"build": "node scripts/build.js",
|
||||
"test": "node scripts/test.js --env=jsdom"
|
||||
},
|
||||
@@ -85,6 +95,11 @@
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"babel": {
|
||||
"presets": [
|
||||
"react-app"
|
||||
]
|
||||
},
|
||||
"jest": {
|
||||
"roots": [
|
||||
"<rootDir>/src"
|
||||
@@ -101,14 +116,15 @@
|
||||
"<rootDir>/src/**/__tests__/**/*.{js,jsx,ts,tsx}",
|
||||
"<rootDir>/src/**/*.{spec,test}.{js,jsx,ts,tsx}"
|
||||
],
|
||||
"testEnvironment": "jest-environment-jsdom-fourteen",
|
||||
"testEnvironment": "jsdom",
|
||||
"testRunner": "<rootDir>/node_modules/jest-circus/runner.js",
|
||||
"transform": {
|
||||
"^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
|
||||
"^.+\\.(js|jsx|mjs|cjs|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
|
||||
"^.+\\.css$": "<rootDir>/config/jest/cssTransform.js",
|
||||
"^(?!.*\\.(js|jsx|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
|
||||
"^(?!.*\\.(js|jsx|mjs|cjs|ts|tsx|css|json)$)": "<rootDir>/config/jest/fileTransform.js"
|
||||
},
|
||||
"transformIgnorePatterns": [
|
||||
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$",
|
||||
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs|cjs|ts|tsx)$",
|
||||
"^.+\\.module\\.(css|sass|scss)$"
|
||||
],
|
||||
"modulePaths": [],
|
||||
@@ -131,11 +147,7 @@
|
||||
"watchPlugins": [
|
||||
"jest-watch-typeahead/filename",
|
||||
"jest-watch-typeahead/testname"
|
||||
]
|
||||
},
|
||||
"babel": {
|
||||
"presets": [
|
||||
"react-app"
|
||||
]
|
||||
],
|
||||
"resetMocks": true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ require('../config/env');
|
||||
const path = require('path');
|
||||
const chalk = require('react-dev-utils/chalk');
|
||||
const fs = require('fs-extra');
|
||||
const bfj = require('bfj');
|
||||
const webpack = require('webpack');
|
||||
const configFactory = require('../config/webpack.config');
|
||||
const paths = require('../config/paths');
|
||||
@@ -42,6 +43,9 @@ if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const argv = process.argv.slice(2);
|
||||
const writeStatsJson = argv.indexOf('--stats') !== -1;
|
||||
|
||||
// Generate configuration
|
||||
const config = configFactory('production');
|
||||
|
||||
@@ -93,7 +97,7 @@ checkBrowsers(paths.appPath, isInteractive)
|
||||
console.log();
|
||||
|
||||
const appPackage = require(paths.appPackageJson);
|
||||
const publicUrl = paths.publicUrl;
|
||||
const publicUrl = paths.publicUrlOrPath;
|
||||
const publicPath = config.output.publicPath;
|
||||
const buildFolder = path.relative(process.cwd(), paths.appBuild);
|
||||
printHostingInstructions(
|
||||
@@ -129,18 +133,6 @@ checkBrowsers(paths.appPath, isInteractive)
|
||||
|
||||
// Create the production build and print the deployment instructions.
|
||||
function build(previousFileSizes) {
|
||||
// We used to support resolving modules according to `NODE_PATH`.
|
||||
// This now has been deprecated in favor of jsconfig/tsconfig.json
|
||||
// This lets you use absolute paths in imports inside large monorepos:
|
||||
if (process.env.NODE_PATH) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.'
|
||||
)
|
||||
);
|
||||
console.log();
|
||||
}
|
||||
|
||||
console.log('Creating an optimized production build...');
|
||||
|
||||
const compiler = webpack(config);
|
||||
@@ -151,8 +143,18 @@ function build(previousFileSizes) {
|
||||
if (!err.message) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
let errMessage = err.message;
|
||||
|
||||
// Add additional information for postcss errors
|
||||
if (Object.prototype.hasOwnProperty.call(err, 'postcssNode')) {
|
||||
errMessage +=
|
||||
'\nCompileError: Begins at CSS selector ' +
|
||||
err['postcssNode'].selector;
|
||||
}
|
||||
|
||||
messages = formatWebpackMessages({
|
||||
errors: [err.message],
|
||||
errors: [errMessage],
|
||||
warnings: [],
|
||||
});
|
||||
} else {
|
||||
@@ -183,11 +185,20 @@ function build(previousFileSizes) {
|
||||
return reject(new Error(messages.warnings.join('\n\n')));
|
||||
}
|
||||
|
||||
return resolve({
|
||||
const resolveArgs = {
|
||||
stats,
|
||||
previousFileSizes,
|
||||
warnings: messages.warnings,
|
||||
});
|
||||
};
|
||||
|
||||
if (writeStatsJson) {
|
||||
return bfj
|
||||
.write(paths.appBuild + '/bundle-stats.json', stats.toJson())
|
||||
.then(() => resolve(resolveArgs))
|
||||
.catch(error => reject(new Error(error)));
|
||||
}
|
||||
|
||||
return resolve(resolveArgs);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
3
fixtures/flight/scripts/package.json
Normal file
3
fixtures/flight/scripts/package.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"type": "commonjs"
|
||||
}
|
||||
@@ -27,10 +27,14 @@ const {
|
||||
prepareUrls,
|
||||
} = require('react-dev-utils/WebpackDevServerUtils');
|
||||
const openBrowser = require('react-dev-utils/openBrowser');
|
||||
const semver = require('semver');
|
||||
const paths = require('../config/paths');
|
||||
const configFactory = require('../config/webpack.config');
|
||||
const createDevServerConfig = require('../config/webpackDevServer.config');
|
||||
const getClientEnvironment = require('../config/env');
|
||||
const react = require(require.resolve('react', {paths: [paths.appPath]}));
|
||||
|
||||
const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1));
|
||||
const useYarn = fs.existsSync(paths.yarnLockFile);
|
||||
const isInteractive = process.stdout.isTTY;
|
||||
|
||||
@@ -55,7 +59,7 @@ if (process.env.HOST) {
|
||||
`If this was unintentional, check that you haven't mistakenly set it in your shell.`
|
||||
);
|
||||
console.log(
|
||||
`Learn more here: ${chalk.yellow('https://bit.ly/CRA-advanced-config')}`
|
||||
`Learn more here: ${chalk.yellow('https://cra.link/advanced-config')}`
|
||||
);
|
||||
console.log();
|
||||
}
|
||||
@@ -74,12 +78,19 @@ checkBrowsers(paths.appPath, isInteractive)
|
||||
// We have not found a port.
|
||||
return;
|
||||
}
|
||||
|
||||
const config = configFactory('development');
|
||||
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
|
||||
const appName = require(paths.appPackageJson).name;
|
||||
|
||||
const useTypeScript = fs.existsSync(paths.appTsConfig);
|
||||
const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
|
||||
const urls = prepareUrls(protocol, HOST, port);
|
||||
const urls = prepareUrls(
|
||||
protocol,
|
||||
HOST,
|
||||
port,
|
||||
paths.publicUrlOrPath.slice(0, -1)
|
||||
);
|
||||
const devSocket = {
|
||||
warnings: warnings =>
|
||||
devServer.sockWrite(devServer.sockets, 'warnings', warnings),
|
||||
@@ -99,7 +110,11 @@ checkBrowsers(paths.appPath, isInteractive)
|
||||
});
|
||||
// Load proxy config
|
||||
const proxySetting = require(paths.appPackageJson).proxy;
|
||||
const proxyConfig = prepareProxy(proxySetting, paths.appPublic);
|
||||
const proxyConfig = prepareProxy(
|
||||
proxySetting,
|
||||
paths.appPublic,
|
||||
paths.publicUrlOrPath
|
||||
);
|
||||
// Serve webpack assets generated by the compiler over a web server.
|
||||
const serverConfig = createDevServerConfig(
|
||||
proxyConfig,
|
||||
@@ -115,16 +130,12 @@ checkBrowsers(paths.appPath, isInteractive)
|
||||
clearConsole();
|
||||
}
|
||||
|
||||
// We used to support resolving modules according to `NODE_PATH`.
|
||||
// This now has been deprecated in favor of jsconfig/tsconfig.json
|
||||
// This lets you use absolute paths in imports inside large monorepos:
|
||||
if (process.env.NODE_PATH) {
|
||||
if (env.raw.FAST_REFRESH && semver.lt(react.version, '16.10.0')) {
|
||||
console.log(
|
||||
chalk.yellow(
|
||||
'Setting NODE_PATH to resolve modules absolutely has been deprecated in favor of setting baseUrl in jsconfig.json (or tsconfig.json if you are using TypeScript) and will be removed in a future major release of create-react-app.'
|
||||
`Fast Refresh requires React 16.10 or higher. You are using React ${react.version}.`
|
||||
)
|
||||
);
|
||||
console.log();
|
||||
}
|
||||
|
||||
console.log(chalk.cyan('Starting the development server...\n'));
|
||||
@@ -137,6 +148,14 @@ checkBrowsers(paths.appPath, isInteractive)
|
||||
process.exit();
|
||||
});
|
||||
});
|
||||
|
||||
if (process.env.CI !== 'true') {
|
||||
// Gracefully exit when stdin ends
|
||||
process.stdin.on('end', function() {
|
||||
devServer.close();
|
||||
process.exit();
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
if (err && err.message) {
|
||||
|
||||
72
fixtures/flight/server/cli.server.js
Normal file
72
fixtures/flight/server/cli.server.js
Normal file
@@ -0,0 +1,72 @@
|
||||
'use strict';
|
||||
|
||||
const register = require('react-server-dom-webpack/node-register');
|
||||
register();
|
||||
|
||||
const babelRegister = require('@babel/register');
|
||||
const path = require('path');
|
||||
|
||||
babelRegister({
|
||||
babelrc: false,
|
||||
ignore: [
|
||||
/\/(build|node_modules)\//,
|
||||
function(file) {
|
||||
if ((path.dirname(file) + '/').startsWith(__dirname + '/')) {
|
||||
// Ignore everything in this folder
|
||||
// because it's a mix of CJS and ESM
|
||||
// and working with raw code is easier.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
],
|
||||
presets: ['react-app'],
|
||||
plugins: ['@babel/transform-modules-commonjs'],
|
||||
});
|
||||
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
|
||||
// Application
|
||||
app.get('/', function(req, res) {
|
||||
require('./handler.server.js')(req, res);
|
||||
});
|
||||
|
||||
app.get('/todos', function(req, res) {
|
||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||
res.json([
|
||||
{
|
||||
id: 1,
|
||||
text: 'Shave yaks',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
text: 'Eat kale',
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
app.listen(3001, () => {
|
||||
console.log('Flight Server listening on port 3001...');
|
||||
});
|
||||
|
||||
app.on('error', function(error) {
|
||||
if (error.syscall !== 'listen') {
|
||||
throw error;
|
||||
}
|
||||
|
||||
var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;
|
||||
|
||||
switch (error.code) {
|
||||
case 'EACCES':
|
||||
console.error(bind + ' requires elevated privileges');
|
||||
process.exit(1);
|
||||
break;
|
||||
case 'EADDRINUSE':
|
||||
console.error(bind + ' is already in use');
|
||||
process.exit(1);
|
||||
break;
|
||||
default:
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
@@ -1,26 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const ReactTransportDOMServer = require('react-transport-dom-webpack/server');
|
||||
const React = require('react');
|
||||
const Stream = require('stream');
|
||||
|
||||
function Text({children}) {
|
||||
return <span>{children}</span>;
|
||||
}
|
||||
|
||||
function HTML() {
|
||||
return (
|
||||
<div>
|
||||
<Text>Hello</Text>
|
||||
<Text>world</Text>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = function(req, res) {
|
||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||
let model = {
|
||||
content: <HTML />,
|
||||
};
|
||||
ReactTransportDOMServer.pipeToNodeWritable(model, res);
|
||||
};
|
||||
27
fixtures/flight/server/handler.server.js
Normal file
27
fixtures/flight/server/handler.server.js
Normal file
@@ -0,0 +1,27 @@
|
||||
'use strict';
|
||||
|
||||
const {pipeToNodeWritable} = require('react-server-dom-webpack/writer');
|
||||
const {readFile} = require('fs');
|
||||
const {resolve} = require('path');
|
||||
const React = require('react');
|
||||
|
||||
module.exports = function(req, res) {
|
||||
// const m = require('../src/App.server.js');
|
||||
import('../src/App.server.js').then(m => {
|
||||
const dist = process.env.NODE_ENV === 'development' ? 'dist' : 'build';
|
||||
readFile(
|
||||
resolve(__dirname, `../${dist}/react-client-manifest.json`),
|
||||
'utf8',
|
||||
(err, data) => {
|
||||
if (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
const App = m.default.default || m.default;
|
||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||
const moduleMap = JSON.parse(data);
|
||||
pipeToNodeWritable(React.createElement(App), res, moduleMap);
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
@@ -1,46 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const babelRegister = require('@babel/register');
|
||||
|
||||
babelRegister({
|
||||
ignore: [/\/(build|node_modules)\//],
|
||||
presets: ['react-app'],
|
||||
});
|
||||
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
|
||||
// Application
|
||||
app.get('/', function(req, res) {
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
for (var key in require.cache) {
|
||||
delete require.cache[key];
|
||||
}
|
||||
}
|
||||
require('./handler')(req, res);
|
||||
});
|
||||
|
||||
app.listen(3001, () => {
|
||||
console.log('Flight Server listening on port 3001...');
|
||||
});
|
||||
|
||||
app.on('error', function(error) {
|
||||
if (error.syscall !== 'listen') {
|
||||
throw error;
|
||||
}
|
||||
|
||||
var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;
|
||||
|
||||
switch (error.code) {
|
||||
case 'EACCES':
|
||||
console.error(bind + ' requires elevated privileges');
|
||||
process.exit(1);
|
||||
break;
|
||||
case 'EADDRINUSE':
|
||||
console.error(bind + ' is already in use');
|
||||
process.exit(1);
|
||||
break;
|
||||
default:
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
4
fixtures/flight/server/package.json
Normal file
4
fixtures/flight/server/package.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"type": "commonjs",
|
||||
"main": "./cli.server.js"
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
import React, {Suspense} from 'react';
|
||||
|
||||
function Content({data}) {
|
||||
return data.readRoot().content;
|
||||
}
|
||||
|
||||
function App({data}) {
|
||||
return (
|
||||
<Suspense fallback={<h1>Loading...</h1>}>
|
||||
<Content data={data} />
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
28
fixtures/flight/src/App.server.js
Normal file
28
fixtures/flight/src/App.server.js
Normal file
@@ -0,0 +1,28 @@
|
||||
import * as React from 'react';
|
||||
import {fetch} from 'react-fetch';
|
||||
|
||||
import Container from './Container.js';
|
||||
|
||||
import {Counter} from './Counter.client.js';
|
||||
import {Counter as Counter2} from './Counter2.client.js';
|
||||
|
||||
import ShowMore from './ShowMore.client.js';
|
||||
|
||||
export default function App() {
|
||||
const todos = fetch('http://localhost:3001/todos').json();
|
||||
return (
|
||||
<Container>
|
||||
<h1>Hello, world</h1>
|
||||
<Counter />
|
||||
<Counter2 />
|
||||
<ul>
|
||||
{todos.map(todo => (
|
||||
<li key={todo.id}>{todo.text}</li>
|
||||
))}
|
||||
</ul>
|
||||
<ShowMore>
|
||||
<p>Lorem ipsum</p>
|
||||
</ShowMore>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
5
fixtures/flight/src/Container.js
Normal file
5
fixtures/flight/src/Container.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import * as React from 'react';
|
||||
|
||||
export default function Container({children}) {
|
||||
return <div>{children}</div>;
|
||||
}
|
||||
12
fixtures/flight/src/Counter.client.js
Normal file
12
fixtures/flight/src/Counter.client.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import Container from './Container.js';
|
||||
|
||||
export function Counter() {
|
||||
const [count, setCount] = React.useState(0);
|
||||
return (
|
||||
<Container>
|
||||
<button onClick={() => setCount(c => c + 1)}>Count: {count}</button>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
1
fixtures/flight/src/Counter2.client.js
Normal file
1
fixtures/flight/src/Counter2.client.js
Normal file
@@ -0,0 +1 @@
|
||||
export * from './Counter.client.js';
|
||||
11
fixtures/flight/src/ShowMore.client.js
Normal file
11
fixtures/flight/src/ShowMore.client.js
Normal file
@@ -0,0 +1,11 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import Container from './Container.js';
|
||||
|
||||
export default function ShowMore({children}) {
|
||||
const [show, setShow] = React.useState(false);
|
||||
if (!show) {
|
||||
return <button onClick={() => setShow(true)}>Show More</button>;
|
||||
}
|
||||
return <Container>{children}</Container>;
|
||||
}
|
||||
@@ -1,10 +1,17 @@
|
||||
import React from 'react';
|
||||
import * as React from 'react';
|
||||
import {Suspense} from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import ReactTransportDOMClient from 'react-transport-dom-webpack';
|
||||
import App from './App';
|
||||
import ReactServerDOMReader from 'react-server-dom-webpack';
|
||||
|
||||
let data = ReactTransportDOMClient.createFromFetch(
|
||||
fetch('http://localhost:3001')
|
||||
let data = ReactServerDOMReader.createFromFetch(fetch('http://localhost:3001'));
|
||||
|
||||
function Content() {
|
||||
return data.readRoot();
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
<Suspense fallback={<h1>Loading...</h1>}>
|
||||
<Content />
|
||||
</Suspense>,
|
||||
document.getElementById('root')
|
||||
);
|
||||
|
||||
ReactDOM.render(<App data={data} />, document.getElementById('root'));
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
12
fixtures/legacy-jsx-runtimes/README.md
Normal file
12
fixtures/legacy-jsx-runtimes/README.md
Normal file
@@ -0,0 +1,12 @@
|
||||
# Legacy JSX Runtimes
|
||||
|
||||
This is an internal testing fixture for the special JSX runtime versions released for 0.14, 15, and 16.
|
||||
|
||||
They are checked into the corresponding `react-*/cjs/*` folders.
|
||||
|
||||
Run the full regression suite:
|
||||
|
||||
```
|
||||
yarn
|
||||
yarn test
|
||||
```
|
||||
12
fixtures/legacy-jsx-runtimes/babel.config.js
Normal file
12
fixtures/legacy-jsx-runtimes/babel.config.js
Normal file
@@ -0,0 +1,12 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
[
|
||||
'@babel/react',
|
||||
{
|
||||
runtime: 'automatic',
|
||||
development: process.env.BABEL_ENV === 'development',
|
||||
},
|
||||
],
|
||||
],
|
||||
plugins: ['@babel/plugin-transform-modules-commonjs'],
|
||||
};
|
||||
63
fixtures/legacy-jsx-runtimes/lint-runtimes.js
Normal file
63
fixtures/legacy-jsx-runtimes/lint-runtimes.js
Normal file
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails react-core
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
|
||||
const {ESLint} = require('eslint');
|
||||
|
||||
function getESLintInstance(format) {
|
||||
return new ESLint({
|
||||
useEslintrc: false,
|
||||
overrideConfigFile:
|
||||
__dirname + `../../../scripts/rollup/validate/eslintrc.${format}.js`,
|
||||
ignore: false,
|
||||
});
|
||||
}
|
||||
|
||||
const esLints = {
|
||||
cjs: getESLintInstance('cjs'),
|
||||
};
|
||||
|
||||
// Performs sanity checks on bundles *built* by Rollup.
|
||||
// Helps catch Rollup regressions.
|
||||
async function lint(folder) {
|
||||
console.log(`Linting ` + folder);
|
||||
const eslint = esLints.cjs;
|
||||
|
||||
const results = await eslint.lintFiles([
|
||||
__dirname + '/' + folder + '/cjs/react-jsx-dev-runtime.development.js',
|
||||
__dirname + '/' + folder + '/cjs/react-jsx-dev-runtime.production.min.js',
|
||||
__dirname + '/' + folder + '/cjs/react-jsx-runtime.development.js',
|
||||
__dirname + '/' + folder + '/cjs/react-jsx-runtime.production.min.js',
|
||||
]);
|
||||
if (
|
||||
results.some(result => result.errorCount > 0 || result.warningCount > 0)
|
||||
) {
|
||||
process.exitCode = 1;
|
||||
console.log(`Failed`);
|
||||
const formatter = await eslint.loadFormatter('stylish');
|
||||
const resultText = formatter.format(results);
|
||||
console.log(resultText);
|
||||
}
|
||||
}
|
||||
|
||||
async function lintEverything() {
|
||||
console.log(`Linting known bundles...`);
|
||||
await lint('react-14');
|
||||
await lint('react-15');
|
||||
await lint('react-16');
|
||||
await lint('react-17');
|
||||
}
|
||||
|
||||
lintEverything().catch(error => {
|
||||
process.exitCode = 1;
|
||||
console.error(error);
|
||||
});
|
||||
19
fixtures/legacy-jsx-runtimes/package.json
Normal file
19
fixtures/legacy-jsx-runtimes/package.json
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"@babel/plugin-transform-modules-commonjs": "^7.10.4",
|
||||
"@babel/preset-react": "^7.10.4",
|
||||
"jest": "^26.5.3"
|
||||
},
|
||||
"jest": {
|
||||
"setupFilesAfterEnv": ["./setupTests.js"]
|
||||
},
|
||||
"scripts": {
|
||||
"install-all": "cd react-14 && yarn && cd ../react-15 && yarn && cd ../react-16 && yarn && cd ../react-17 && yarn && cd ..",
|
||||
"lint": "node lint-runtimes.js",
|
||||
"pretest": "yarn install-all && yarn lint",
|
||||
"test-jsxdev-dev": "BABEL_ENV=development NODE_ENV=development jest",
|
||||
"test-jsx-dev": "BABEL_ENV=production NODE_ENV=development jest",
|
||||
"test-jsx-prod": "BABEL_ENV=production NODE_ENV=production jest",
|
||||
"test": "yarn test-jsxdev-dev && yarn test-jsx-dev && yarn test-jsx-prod"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,861 @@
|
||||
/** @license React v0.14.10
|
||||
* react-jsx-dev-runtime.development.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
|
||||
// ATTENTION
|
||||
// When adding new symbols to this file,
|
||||
// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
|
||||
// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
|
||||
// nor polyfill, then a plain number is used for performance.
|
||||
var REACT_ELEMENT_TYPE = 0xeac7;
|
||||
var REACT_PORTAL_TYPE = 0xeaca;
|
||||
exports.Fragment = 0xeacb;
|
||||
var REACT_STRICT_MODE_TYPE = 0xeacc;
|
||||
var REACT_PROFILER_TYPE = 0xead2;
|
||||
var REACT_PROVIDER_TYPE = 0xeacd;
|
||||
var REACT_CONTEXT_TYPE = 0xeace;
|
||||
var REACT_FORWARD_REF_TYPE = 0xead0;
|
||||
var REACT_SUSPENSE_TYPE = 0xead1;
|
||||
var REACT_SUSPENSE_LIST_TYPE = 0xead8;
|
||||
var REACT_MEMO_TYPE = 0xead3;
|
||||
var REACT_LAZY_TYPE = 0xead4;
|
||||
var REACT_BLOCK_TYPE = 0xead9;
|
||||
var REACT_SERVER_BLOCK_TYPE = 0xeada;
|
||||
var REACT_FUNDAMENTAL_TYPE = 0xead5;
|
||||
var REACT_SCOPE_TYPE = 0xead7;
|
||||
var REACT_OPAQUE_ID_TYPE = 0xeae0;
|
||||
var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1;
|
||||
var REACT_OFFSCREEN_TYPE = 0xeae2;
|
||||
var REACT_LEGACY_HIDDEN_TYPE = 0xeae3;
|
||||
|
||||
if (typeof Symbol === 'function' && Symbol.for) {
|
||||
var symbolFor = Symbol.for;
|
||||
REACT_ELEMENT_TYPE = symbolFor('react.element');
|
||||
REACT_PORTAL_TYPE = symbolFor('react.portal');
|
||||
exports.Fragment = symbolFor('react.fragment');
|
||||
REACT_STRICT_MODE_TYPE = symbolFor('react.strict_mode');
|
||||
REACT_PROFILER_TYPE = symbolFor('react.profiler');
|
||||
REACT_PROVIDER_TYPE = symbolFor('react.provider');
|
||||
REACT_CONTEXT_TYPE = symbolFor('react.context');
|
||||
REACT_FORWARD_REF_TYPE = symbolFor('react.forward_ref');
|
||||
REACT_SUSPENSE_TYPE = symbolFor('react.suspense');
|
||||
REACT_SUSPENSE_LIST_TYPE = symbolFor('react.suspense_list');
|
||||
REACT_MEMO_TYPE = symbolFor('react.memo');
|
||||
REACT_LAZY_TYPE = symbolFor('react.lazy');
|
||||
REACT_BLOCK_TYPE = symbolFor('react.block');
|
||||
REACT_SERVER_BLOCK_TYPE = symbolFor('react.server.block');
|
||||
REACT_FUNDAMENTAL_TYPE = symbolFor('react.fundamental');
|
||||
REACT_SCOPE_TYPE = symbolFor('react.scope');
|
||||
REACT_OPAQUE_ID_TYPE = symbolFor('react.opaque.id');
|
||||
REACT_DEBUG_TRACING_MODE_TYPE = symbolFor('react.debug_trace_mode');
|
||||
REACT_OFFSCREEN_TYPE = symbolFor('react.offscreen');
|
||||
REACT_LEGACY_HIDDEN_TYPE = symbolFor('react.legacy_hidden');
|
||||
}
|
||||
|
||||
var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
|
||||
var FAUX_ITERATOR_SYMBOL = '@@iterator';
|
||||
function getIteratorFn(maybeIterable) {
|
||||
if (maybeIterable === null || typeof maybeIterable !== 'object') {
|
||||
return null;
|
||||
}
|
||||
|
||||
var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
|
||||
|
||||
if (typeof maybeIterator === 'function') {
|
||||
return maybeIterator;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function error(format) {
|
||||
{
|
||||
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
||||
args[_key2 - 1] = arguments[_key2];
|
||||
}
|
||||
|
||||
printWarning('error', format, args);
|
||||
}
|
||||
}
|
||||
|
||||
function printWarning(level, format, args) {
|
||||
// When changing this logic, you might want to also
|
||||
// update consoleWithStackDev.www.js as well.
|
||||
{
|
||||
var stack = '';
|
||||
|
||||
|
||||
if (stack !== '') {
|
||||
format += '%s';
|
||||
args = args.concat([stack]);
|
||||
}
|
||||
|
||||
var argsWithFormat = args.map(function (item) {
|
||||
return '' + item;
|
||||
}); // Careful: RN currently depends on this prefix
|
||||
|
||||
argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
|
||||
// breaks IE9: https://github.com/facebook/react/issues/13610
|
||||
// eslint-disable-next-line react-internal/no-production-logging
|
||||
|
||||
Function.prototype.apply.call(console[level], console, argsWithFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// Filter certain DOM attributes (e.g. src, href) if their values are empty strings.
|
||||
|
||||
var enableScopeAPI = false; // Experimental Create Event Handle API.
|
||||
|
||||
function isValidElementType(type) {
|
||||
if (typeof type === 'string' || typeof type === 'function') {
|
||||
return true;
|
||||
} // Note: typeof might be other than 'symbol' or 'number' (e.g. if it's a polyfill).
|
||||
|
||||
|
||||
if (type === exports.Fragment || type === REACT_PROFILER_TYPE || type === REACT_DEBUG_TRACING_MODE_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || type === REACT_LEGACY_HIDDEN_TYPE || enableScopeAPI ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof type === 'object' && type !== null) {
|
||||
if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_BLOCK_TYPE || type[0] === REACT_SERVER_BLOCK_TYPE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
|
||||
function describeComponentFrame (name, source, ownerName) {
|
||||
var sourceInfo = '';
|
||||
|
||||
if (source) {
|
||||
var path = source.fileName;
|
||||
var fileName = path.replace(BEFORE_SLASH_RE, '');
|
||||
|
||||
{
|
||||
// In DEV, include code for a common special case:
|
||||
// prefer "folder/index.js" instead of just "index.js".
|
||||
if (/^index\./.test(fileName)) {
|
||||
var match = path.match(BEFORE_SLASH_RE);
|
||||
|
||||
if (match) {
|
||||
var pathBeforeSlash = match[1];
|
||||
|
||||
if (pathBeforeSlash) {
|
||||
var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
|
||||
fileName = folderName + '/' + fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
|
||||
} else if (ownerName) {
|
||||
sourceInfo = ' (created by ' + ownerName + ')';
|
||||
}
|
||||
|
||||
return '\n in ' + (name || 'Unknown') + sourceInfo;
|
||||
}
|
||||
|
||||
var Resolved = 1;
|
||||
function refineResolvedLazyComponent(lazyComponent) {
|
||||
return lazyComponent._status === Resolved ? lazyComponent._result : null;
|
||||
}
|
||||
|
||||
function getWrappedName(outerType, innerType, wrapperName) {
|
||||
var functionName = innerType.displayName || innerType.name || '';
|
||||
return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
|
||||
}
|
||||
|
||||
function getComponentName(type) {
|
||||
if (type == null) {
|
||||
// Host root, text node or just invalid type.
|
||||
return null;
|
||||
}
|
||||
|
||||
{
|
||||
if (typeof type.tag === 'number') {
|
||||
error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof type === 'function') {
|
||||
return type.displayName || type.name || null;
|
||||
}
|
||||
|
||||
if (typeof type === 'string') {
|
||||
return type;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case exports.Fragment:
|
||||
return 'Fragment';
|
||||
|
||||
case REACT_PORTAL_TYPE:
|
||||
return 'Portal';
|
||||
|
||||
case REACT_PROFILER_TYPE:
|
||||
return "Profiler";
|
||||
|
||||
case REACT_STRICT_MODE_TYPE:
|
||||
return 'StrictMode';
|
||||
|
||||
case REACT_SUSPENSE_TYPE:
|
||||
return 'Suspense';
|
||||
|
||||
case REACT_SUSPENSE_LIST_TYPE:
|
||||
return 'SuspenseList';
|
||||
}
|
||||
|
||||
if (typeof type === 'object') {
|
||||
switch (type.$$typeof) {
|
||||
case REACT_CONTEXT_TYPE:
|
||||
return 'Context.Consumer';
|
||||
|
||||
case REACT_PROVIDER_TYPE:
|
||||
return 'Context.Provider';
|
||||
|
||||
case REACT_FORWARD_REF_TYPE:
|
||||
return getWrappedName(type, type.render, 'ForwardRef');
|
||||
|
||||
case REACT_MEMO_TYPE:
|
||||
return getComponentName(type.type);
|
||||
|
||||
case REACT_BLOCK_TYPE:
|
||||
return getComponentName(type.render);
|
||||
|
||||
case REACT_LAZY_TYPE:
|
||||
{
|
||||
var thenable = type;
|
||||
var resolvedThenable = refineResolvedLazyComponent(thenable);
|
||||
|
||||
if (resolvedThenable) {
|
||||
return getComponentName(resolvedThenable);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
var loggedTypeFailures = {};
|
||||
var currentlyValidatingElement = null;
|
||||
|
||||
function setCurrentlyValidatingElement(element) {
|
||||
currentlyValidatingElement = element;
|
||||
}
|
||||
|
||||
function checkPropTypes(typeSpecs, values, location, componentName, element) {
|
||||
{
|
||||
// $FlowFixMe This is okay but Flow doesn't know it.
|
||||
var has = Function.call.bind(Object.prototype.hasOwnProperty);
|
||||
|
||||
for (var typeSpecName in typeSpecs) {
|
||||
if (has(typeSpecs, typeSpecName)) {
|
||||
var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
|
||||
// fail the render phase where it didn't fail before. So we log it.
|
||||
// After these have been cleaned up, we'll let them throw.
|
||||
|
||||
try {
|
||||
// This is intentionally an invariant that gets caught. It's the same
|
||||
// behavior as without this statement except with a better message.
|
||||
if (typeof typeSpecs[typeSpecName] !== 'function') {
|
||||
var err = Error((componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.');
|
||||
err.name = 'Invariant Violation';
|
||||
throw err;
|
||||
}
|
||||
|
||||
error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
|
||||
} catch (ex) {
|
||||
error$1 = ex;
|
||||
}
|
||||
|
||||
if (error$1 && !(error$1 instanceof Error)) {
|
||||
setCurrentlyValidatingElement(element);
|
||||
|
||||
error('%s: type specification of %s' + ' `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error$1);
|
||||
|
||||
setCurrentlyValidatingElement(null);
|
||||
}
|
||||
|
||||
if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
|
||||
// Only monitor this failure once because there tends to be a lot of the
|
||||
// same error.
|
||||
loggedTypeFailures[error$1.message] = true;
|
||||
setCurrentlyValidatingElement(element);
|
||||
|
||||
error('Failed %s type: %s', location, error$1.message);
|
||||
|
||||
setCurrentlyValidatingElement(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ReactCurrentOwner = require('react/lib/ReactCurrentOwner');
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
var RESERVED_PROPS = {
|
||||
key: true,
|
||||
ref: true,
|
||||
__self: true,
|
||||
__source: true
|
||||
};
|
||||
var specialPropKeyWarningShown;
|
||||
var specialPropRefWarningShown;
|
||||
var didWarnAboutStringRefs;
|
||||
|
||||
{
|
||||
didWarnAboutStringRefs = {};
|
||||
}
|
||||
|
||||
function hasValidRef(config) {
|
||||
{
|
||||
if (hasOwnProperty.call(config, 'ref')) {
|
||||
var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
|
||||
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return config.ref !== undefined;
|
||||
}
|
||||
|
||||
function hasValidKey(config) {
|
||||
{
|
||||
if (hasOwnProperty.call(config, 'key')) {
|
||||
var getter = Object.getOwnPropertyDescriptor(config, 'key').get;
|
||||
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return config.key !== undefined;
|
||||
}
|
||||
|
||||
function defineKeyPropWarningGetter(props, displayName) {
|
||||
{
|
||||
var warnAboutAccessingKey = function () {
|
||||
if (!specialPropKeyWarningShown) {
|
||||
specialPropKeyWarningShown = true;
|
||||
|
||||
error('%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);
|
||||
}
|
||||
};
|
||||
|
||||
warnAboutAccessingKey.isReactWarning = true;
|
||||
Object.defineProperty(props, 'key', {
|
||||
get: warnAboutAccessingKey,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function defineRefPropWarningGetter(props, displayName) {
|
||||
{
|
||||
var warnAboutAccessingRef = function () {
|
||||
if (!specialPropRefWarningShown) {
|
||||
specialPropRefWarningShown = true;
|
||||
|
||||
error('%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);
|
||||
}
|
||||
};
|
||||
|
||||
warnAboutAccessingRef.isReactWarning = true;
|
||||
Object.defineProperty(props, 'ref', {
|
||||
get: warnAboutAccessingRef,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Factory method to create a new React element. This no longer adheres to
|
||||
* the class pattern, so do not use new to call it. Also, instanceof check
|
||||
* will not work. Instead test $$typeof field against Symbol.for('react.element') to check
|
||||
* if something is a React Element.
|
||||
*
|
||||
* @param {*} type
|
||||
* @param {*} props
|
||||
* @param {*} key
|
||||
* @param {string|object} ref
|
||||
* @param {*} owner
|
||||
* @param {*} self A *temporary* helper to detect places where `this` is
|
||||
* different from the `owner` when React.createElement is called, so that we
|
||||
* can warn. We want to get rid of owner and replace string `ref`s with arrow
|
||||
* functions, and as long as `this` and owner are the same, there will be no
|
||||
* change in behavior.
|
||||
* @param {*} source An annotation object (added by a transpiler or otherwise)
|
||||
* indicating filename, line number, and/or other information.
|
||||
* @internal
|
||||
*/
|
||||
|
||||
|
||||
var ReactElement = function (type, key, ref, self, source, owner, props) {
|
||||
var element = {
|
||||
// This tag allows us to uniquely identify this as a React Element
|
||||
$$typeof: REACT_ELEMENT_TYPE,
|
||||
// Built-in properties that belong on the element
|
||||
type: type,
|
||||
key: key,
|
||||
ref: ref,
|
||||
props: props,
|
||||
// Record the component responsible for creating this element.
|
||||
_owner: owner
|
||||
};
|
||||
|
||||
{
|
||||
// The validation flag is currently mutative. We put it on
|
||||
// an external backing store so that we can freeze the whole object.
|
||||
// This can be replaced with a WeakMap once they are implemented in
|
||||
// commonly used development environments.
|
||||
element._store = {}; // To make comparing ReactElements easier for testing purposes, we make
|
||||
// the validation flag non-enumerable (where possible, which should
|
||||
// include every environment we run tests in), so the test framework
|
||||
// ignores it.
|
||||
|
||||
Object.defineProperty(element._store, 'validated', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
value: false
|
||||
}); // self and source are DEV only properties.
|
||||
|
||||
Object.defineProperty(element, '_self', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: self
|
||||
}); // Two elements created in two different places should be considered
|
||||
// equal for testing purposes and therefore we hide it from enumeration.
|
||||
|
||||
Object.defineProperty(element, '_source', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: source
|
||||
});
|
||||
|
||||
if (Object.freeze) {
|
||||
Object.freeze(element.props);
|
||||
Object.freeze(element);
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
};
|
||||
/**
|
||||
* https://github.com/reactjs/rfcs/pull/107
|
||||
* @param {*} type
|
||||
* @param {object} props
|
||||
* @param {string} key
|
||||
*/
|
||||
|
||||
function jsxDEV(type, config, maybeKey, source, self) {
|
||||
{
|
||||
var propName; // Reserved names are extracted
|
||||
|
||||
var props = {};
|
||||
var key = null;
|
||||
var ref = null; // Currently, key can be spread in as a prop. This causes a potential
|
||||
// issue if key is also explicitly declared (ie. <div {...props} key="Hi" />
|
||||
// or <div key="Hi" {...props} /> ). We want to deprecate key spread,
|
||||
// but as an intermediary step, we will use jsxDEV for everything except
|
||||
// <div {...props} key="Hi" />, because we aren't currently able to tell if
|
||||
// key is explicitly declared to be undefined or not.
|
||||
|
||||
if (maybeKey !== undefined) {
|
||||
key = '' + maybeKey;
|
||||
}
|
||||
|
||||
if (hasValidKey(config)) {
|
||||
key = '' + config.key;
|
||||
}
|
||||
|
||||
if (hasValidRef(config)) {
|
||||
ref = config.ref;
|
||||
} // Remaining properties are added to a new props object
|
||||
|
||||
|
||||
for (propName in config) {
|
||||
if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
|
||||
props[propName] = config[propName];
|
||||
}
|
||||
} // Resolve default props
|
||||
|
||||
|
||||
if (type && type.defaultProps) {
|
||||
var defaultProps = type.defaultProps;
|
||||
|
||||
for (propName in defaultProps) {
|
||||
if (props[propName] === undefined) {
|
||||
props[propName] = defaultProps[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (key || ref) {
|
||||
var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type;
|
||||
|
||||
if (key) {
|
||||
defineKeyPropWarningGetter(props, displayName);
|
||||
}
|
||||
|
||||
if (ref) {
|
||||
defineRefPropWarningGetter(props, displayName);
|
||||
}
|
||||
}
|
||||
|
||||
return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
|
||||
}
|
||||
}
|
||||
|
||||
var ReactCurrentOwner$1 = require('react/lib/ReactCurrentOwner');
|
||||
|
||||
function setCurrentlyValidatingElement$1(element) {
|
||||
currentlyValidatingElement = element;
|
||||
}
|
||||
|
||||
var propTypesMisspellWarningShown;
|
||||
|
||||
{
|
||||
propTypesMisspellWarningShown = false;
|
||||
}
|
||||
/**
|
||||
* Verifies the object is a ReactElement.
|
||||
* See https://reactjs.org/docs/react-api.html#isvalidelement
|
||||
* @param {?object} object
|
||||
* @return {boolean} True if `object` is a ReactElement.
|
||||
* @final
|
||||
*/
|
||||
|
||||
function isValidElement(object) {
|
||||
{
|
||||
return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
function getDeclarationErrorAddendum() {
|
||||
{
|
||||
if (ReactCurrentOwner$1.current) {
|
||||
var name = ReactCurrentOwner$1.current.getName();
|
||||
|
||||
if (name) {
|
||||
return '\n\nCheck the render method of `' + name + '`.';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceInfoErrorAddendum(source) {
|
||||
{
|
||||
if (source !== undefined) {
|
||||
var fileName = source.fileName.replace(/^.*[\\\/]/, '');
|
||||
var lineNumber = source.lineNumber;
|
||||
return '\n\nCheck your code at ' + fileName + ':' + lineNumber + '.';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Warn if there's no key explicitly set on dynamic arrays of children or
|
||||
* object keys are not valid. This allows us to keep track of children between
|
||||
* updates.
|
||||
*/
|
||||
|
||||
|
||||
var ownerHasKeyUseWarning = {};
|
||||
|
||||
function getCurrentComponentErrorInfo(parentType) {
|
||||
{
|
||||
var info = getDeclarationErrorAddendum();
|
||||
|
||||
if (!info) {
|
||||
var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;
|
||||
|
||||
if (parentName) {
|
||||
info = "\n\nCheck the top-level render call using <" + parentName + ">.";
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Warn if the element doesn't have an explicit key assigned to it.
|
||||
* This element is in an array. The array could grow and shrink or be
|
||||
* reordered. All children that haven't already been validated are required to
|
||||
* have a "key" property assigned to it. Error statuses are cached so a warning
|
||||
* will only be shown once.
|
||||
*
|
||||
* @internal
|
||||
* @param {ReactElement} element Element that requires a key.
|
||||
* @param {*} parentType element's parent's type.
|
||||
*/
|
||||
|
||||
|
||||
function validateExplicitKey(element, parentType) {
|
||||
{
|
||||
if (!element._store || element._store.validated || element.key != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
element._store.validated = true;
|
||||
var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType);
|
||||
|
||||
if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
|
||||
return;
|
||||
}
|
||||
|
||||
ownerHasKeyUseWarning[currentComponentErrorInfo] = true; // Usually the current owner is the offender, but if it accepts children as a
|
||||
// property, it may be the creator of the child that's responsible for
|
||||
// assigning it a key.
|
||||
|
||||
var childOwner = '';
|
||||
|
||||
if (element && element._owner && element._owner !== ReactCurrentOwner$1.current) {
|
||||
// Give the component that originally created this child.
|
||||
childOwner = " It was passed a child from " + element._owner.getName() + ".";
|
||||
}
|
||||
|
||||
setCurrentlyValidatingElement$1(element);
|
||||
|
||||
error('Each child in a list should have a unique "key" prop.' + '%s%s See https://reactjs.org/link/warning-keys for more information.', currentComponentErrorInfo, childOwner);
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Ensure that every element either is passed in a static location, in an
|
||||
* array with an explicit keys property defined, or in an object literal
|
||||
* with valid key property.
|
||||
*
|
||||
* @internal
|
||||
* @param {ReactNode} node Statically passed child of any type.
|
||||
* @param {*} parentType node's parent's type.
|
||||
*/
|
||||
|
||||
|
||||
function validateChildKeys(node, parentType) {
|
||||
{
|
||||
if (typeof node !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.isArray(node)) {
|
||||
for (var i = 0; i < node.length; i++) {
|
||||
var child = node[i];
|
||||
|
||||
if (isValidElement(child)) {
|
||||
validateExplicitKey(child, parentType);
|
||||
}
|
||||
}
|
||||
} else if (isValidElement(node)) {
|
||||
// This element was passed in a valid location.
|
||||
if (node._store) {
|
||||
node._store.validated = true;
|
||||
}
|
||||
} else if (node) {
|
||||
var iteratorFn = getIteratorFn(node);
|
||||
|
||||
if (typeof iteratorFn === 'function') {
|
||||
// Entry iterators used to provide implicit keys,
|
||||
// but now we print a separate warning for them later.
|
||||
if (iteratorFn !== node.entries) {
|
||||
var iterator = iteratorFn.call(node);
|
||||
var step;
|
||||
|
||||
while (!(step = iterator.next()).done) {
|
||||
if (isValidElement(step.value)) {
|
||||
validateExplicitKey(step.value, parentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Given an element, validate that its props follow the propTypes definition,
|
||||
* provided by the type.
|
||||
*
|
||||
* @param {ReactElement} element
|
||||
*/
|
||||
|
||||
|
||||
function validatePropTypes(element) {
|
||||
{
|
||||
var type = element.type;
|
||||
|
||||
if (type === null || type === undefined || typeof type === 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
var propTypes;
|
||||
|
||||
if (typeof type === 'function') {
|
||||
propTypes = type.propTypes;
|
||||
} else if (typeof type === 'object' && (type.$$typeof === REACT_FORWARD_REF_TYPE || // Note: Memo only checks outer props here.
|
||||
// Inner props are checked in the reconciler.
|
||||
type.$$typeof === REACT_MEMO_TYPE)) {
|
||||
propTypes = type.propTypes;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (propTypes) {
|
||||
// Intentionally inside to avoid triggering lazy initializers:
|
||||
var name = getComponentName(type);
|
||||
checkPropTypes(propTypes, element.props, 'prop', name, element);
|
||||
} else if (type.PropTypes !== undefined && !propTypesMisspellWarningShown) {
|
||||
propTypesMisspellWarningShown = true; // Intentionally inside to avoid triggering lazy initializers:
|
||||
|
||||
var _name = getComponentName(type);
|
||||
|
||||
error('Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?', _name || 'Unknown');
|
||||
}
|
||||
|
||||
if (typeof type.getDefaultProps === 'function' && !type.getDefaultProps.isReactClassApproved) {
|
||||
error('getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.');
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Given a fragment, validate that it can only be provided with fragment props
|
||||
* @param {ReactElement} fragment
|
||||
*/
|
||||
|
||||
|
||||
function validateFragmentProps(fragment) {
|
||||
{
|
||||
var keys = Object.keys(fragment.props);
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
|
||||
if (key !== 'children' && key !== 'key') {
|
||||
setCurrentlyValidatingElement$1(fragment);
|
||||
|
||||
error('Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key);
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fragment.ref !== null) {
|
||||
setCurrentlyValidatingElement$1(fragment);
|
||||
|
||||
error('Invalid attribute `ref` supplied to `React.Fragment`.');
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function jsxWithValidation(type, props, key, isStaticChildren, source, self) {
|
||||
{
|
||||
var validType = isValidElementType(type); // We warn in this case but don't throw. We expect the element creation to
|
||||
// succeed and there will likely be errors in render.
|
||||
|
||||
if (!validType) {
|
||||
var info = '';
|
||||
|
||||
if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
|
||||
info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and named imports.";
|
||||
}
|
||||
|
||||
var sourceInfo = getSourceInfoErrorAddendum(source);
|
||||
|
||||
if (sourceInfo) {
|
||||
info += sourceInfo;
|
||||
} else {
|
||||
info += getDeclarationErrorAddendum();
|
||||
}
|
||||
|
||||
var typeString;
|
||||
|
||||
if (type === null) {
|
||||
typeString = 'null';
|
||||
} else if (Array.isArray(type)) {
|
||||
typeString = 'array';
|
||||
} else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {
|
||||
typeString = "<" + (getComponentName(type.type) || 'Unknown') + " />";
|
||||
info = ' Did you accidentally export a JSX literal instead of a component?';
|
||||
} else {
|
||||
typeString = typeof type;
|
||||
}
|
||||
|
||||
error('React.jsx: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', typeString, info);
|
||||
}
|
||||
|
||||
var element = jsxDEV(type, props, key, source, self); // The result can be nullish if a mock or a custom function is used.
|
||||
// TODO: Drop this when these are no longer allowed as the type argument.
|
||||
|
||||
if (element == null) {
|
||||
return element;
|
||||
} // Skip key warning if the type isn't valid since our key validation logic
|
||||
// doesn't expect a non-string/function type and can throw confusing errors.
|
||||
// We don't want exception behavior to differ between dev and prod.
|
||||
// (Rendering will throw with a helpful message and as soon as the type is
|
||||
// fixed, the key warnings will appear.)
|
||||
|
||||
|
||||
if (validType) {
|
||||
var children = props.children;
|
||||
|
||||
if (children !== undefined) {
|
||||
if (isStaticChildren) {
|
||||
if (Array.isArray(children)) {
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
validateChildKeys(children[i], type);
|
||||
}
|
||||
|
||||
if (Object.freeze) {
|
||||
Object.freeze(children);
|
||||
}
|
||||
} else {
|
||||
error('React.jsx: Static children should always be an array. ' + 'You are likely explicitly calling React.jsxs or React.jsxDEV. ' + 'Use the Babel transform instead.');
|
||||
}
|
||||
} else {
|
||||
validateChildKeys(children, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type === exports.Fragment) {
|
||||
validateFragmentProps(element);
|
||||
} else {
|
||||
validatePropTypes(element);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
} // These two functions exist to still get child warnings in dev
|
||||
|
||||
var jsxDEV$1 = jsxWithValidation ;
|
||||
|
||||
exports.jsxDEV = jsxDEV$1;
|
||||
})();
|
||||
}
|
||||
9
fixtures/legacy-jsx-runtimes/react-14/cjs/react-jsx-dev-runtime.production.min.js
vendored
Normal file
9
fixtures/legacy-jsx-runtimes/react-14/cjs/react-jsx-dev-runtime.production.min.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/** @license React v0.14.10
|
||||
* react-jsx-dev-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
'use strict';require("react");exports.Fragment=60107;if("function"===typeof Symbol&&Symbol.for){var a=Symbol.for;exports.Fragment=a("react.fragment")}exports.jsxDEV=void 0;
|
||||
@@ -0,0 +1,883 @@
|
||||
/** @license React v0.14.10
|
||||
* react-jsx-runtime.development.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
|
||||
// ATTENTION
|
||||
// When adding new symbols to this file,
|
||||
// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
|
||||
// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
|
||||
// nor polyfill, then a plain number is used for performance.
|
||||
var REACT_ELEMENT_TYPE = 0xeac7;
|
||||
var REACT_PORTAL_TYPE = 0xeaca;
|
||||
exports.Fragment = 0xeacb;
|
||||
var REACT_STRICT_MODE_TYPE = 0xeacc;
|
||||
var REACT_PROFILER_TYPE = 0xead2;
|
||||
var REACT_PROVIDER_TYPE = 0xeacd;
|
||||
var REACT_CONTEXT_TYPE = 0xeace;
|
||||
var REACT_FORWARD_REF_TYPE = 0xead0;
|
||||
var REACT_SUSPENSE_TYPE = 0xead1;
|
||||
var REACT_SUSPENSE_LIST_TYPE = 0xead8;
|
||||
var REACT_MEMO_TYPE = 0xead3;
|
||||
var REACT_LAZY_TYPE = 0xead4;
|
||||
var REACT_BLOCK_TYPE = 0xead9;
|
||||
var REACT_SERVER_BLOCK_TYPE = 0xeada;
|
||||
var REACT_FUNDAMENTAL_TYPE = 0xead5;
|
||||
var REACT_SCOPE_TYPE = 0xead7;
|
||||
var REACT_OPAQUE_ID_TYPE = 0xeae0;
|
||||
var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1;
|
||||
var REACT_OFFSCREEN_TYPE = 0xeae2;
|
||||
var REACT_LEGACY_HIDDEN_TYPE = 0xeae3;
|
||||
|
||||
if (typeof Symbol === 'function' && Symbol.for) {
|
||||
var symbolFor = Symbol.for;
|
||||
REACT_ELEMENT_TYPE = symbolFor('react.element');
|
||||
REACT_PORTAL_TYPE = symbolFor('react.portal');
|
||||
exports.Fragment = symbolFor('react.fragment');
|
||||
REACT_STRICT_MODE_TYPE = symbolFor('react.strict_mode');
|
||||
REACT_PROFILER_TYPE = symbolFor('react.profiler');
|
||||
REACT_PROVIDER_TYPE = symbolFor('react.provider');
|
||||
REACT_CONTEXT_TYPE = symbolFor('react.context');
|
||||
REACT_FORWARD_REF_TYPE = symbolFor('react.forward_ref');
|
||||
REACT_SUSPENSE_TYPE = symbolFor('react.suspense');
|
||||
REACT_SUSPENSE_LIST_TYPE = symbolFor('react.suspense_list');
|
||||
REACT_MEMO_TYPE = symbolFor('react.memo');
|
||||
REACT_LAZY_TYPE = symbolFor('react.lazy');
|
||||
REACT_BLOCK_TYPE = symbolFor('react.block');
|
||||
REACT_SERVER_BLOCK_TYPE = symbolFor('react.server.block');
|
||||
REACT_FUNDAMENTAL_TYPE = symbolFor('react.fundamental');
|
||||
REACT_SCOPE_TYPE = symbolFor('react.scope');
|
||||
REACT_OPAQUE_ID_TYPE = symbolFor('react.opaque.id');
|
||||
REACT_DEBUG_TRACING_MODE_TYPE = symbolFor('react.debug_trace_mode');
|
||||
REACT_OFFSCREEN_TYPE = symbolFor('react.offscreen');
|
||||
REACT_LEGACY_HIDDEN_TYPE = symbolFor('react.legacy_hidden');
|
||||
}
|
||||
|
||||
var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
|
||||
var FAUX_ITERATOR_SYMBOL = '@@iterator';
|
||||
function getIteratorFn(maybeIterable) {
|
||||
if (maybeIterable === null || typeof maybeIterable !== 'object') {
|
||||
return null;
|
||||
}
|
||||
|
||||
var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
|
||||
|
||||
if (typeof maybeIterator === 'function') {
|
||||
return maybeIterator;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function error(format) {
|
||||
{
|
||||
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
||||
args[_key2 - 1] = arguments[_key2];
|
||||
}
|
||||
|
||||
printWarning('error', format, args);
|
||||
}
|
||||
}
|
||||
|
||||
function printWarning(level, format, args) {
|
||||
// When changing this logic, you might want to also
|
||||
// update consoleWithStackDev.www.js as well.
|
||||
{
|
||||
var stack = '';
|
||||
|
||||
if (stack !== '') {
|
||||
format += '%s';
|
||||
args = args.concat([stack]);
|
||||
}
|
||||
|
||||
var argsWithFormat = args.map(function (item) {
|
||||
return '' + item;
|
||||
}); // Careful: RN currently depends on this prefix
|
||||
|
||||
argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
|
||||
// breaks IE9: https://github.com/facebook/react/issues/13610
|
||||
// eslint-disable-next-line react-internal/no-production-logging
|
||||
|
||||
Function.prototype.apply.call(console[level], console, argsWithFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// Filter certain DOM attributes (e.g. src, href) if their values are empty strings.
|
||||
|
||||
var enableScopeAPI = false; // Experimental Create Event Handle API.
|
||||
|
||||
function isValidElementType(type) {
|
||||
if (typeof type === 'string' || typeof type === 'function') {
|
||||
return true;
|
||||
} // Note: typeof might be other than 'symbol' or 'number' (e.g. if it's a polyfill).
|
||||
|
||||
|
||||
if (type === exports.Fragment || type === REACT_PROFILER_TYPE || type === REACT_DEBUG_TRACING_MODE_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || type === REACT_LEGACY_HIDDEN_TYPE || enableScopeAPI ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof type === 'object' && type !== null) {
|
||||
if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_BLOCK_TYPE || type[0] === REACT_SERVER_BLOCK_TYPE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
|
||||
function describeComponentFrame (name, source, ownerName) {
|
||||
var sourceInfo = '';
|
||||
|
||||
if (source) {
|
||||
var path = source.fileName;
|
||||
var fileName = path.replace(BEFORE_SLASH_RE, '');
|
||||
|
||||
{
|
||||
// In DEV, include code for a common special case:
|
||||
// prefer "folder/index.js" instead of just "index.js".
|
||||
if (/^index\./.test(fileName)) {
|
||||
var match = path.match(BEFORE_SLASH_RE);
|
||||
|
||||
if (match) {
|
||||
var pathBeforeSlash = match[1];
|
||||
|
||||
if (pathBeforeSlash) {
|
||||
var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
|
||||
fileName = folderName + '/' + fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
|
||||
} else if (ownerName) {
|
||||
sourceInfo = ' (created by ' + ownerName + ')';
|
||||
}
|
||||
|
||||
return '\n in ' + (name || 'Unknown') + sourceInfo;
|
||||
}
|
||||
|
||||
var Resolved = 1;
|
||||
function refineResolvedLazyComponent(lazyComponent) {
|
||||
return lazyComponent._status === Resolved ? lazyComponent._result : null;
|
||||
}
|
||||
|
||||
function getWrappedName(outerType, innerType, wrapperName) {
|
||||
var functionName = innerType.displayName || innerType.name || '';
|
||||
return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
|
||||
}
|
||||
|
||||
function getComponentName(type) {
|
||||
if (type == null) {
|
||||
// Host root, text node or just invalid type.
|
||||
return null;
|
||||
}
|
||||
|
||||
{
|
||||
if (typeof type.tag === 'number') {
|
||||
error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof type === 'function') {
|
||||
return type.displayName || type.name || null;
|
||||
}
|
||||
|
||||
if (typeof type === 'string') {
|
||||
return type;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case exports.Fragment:
|
||||
return 'Fragment';
|
||||
|
||||
case REACT_PORTAL_TYPE:
|
||||
return 'Portal';
|
||||
|
||||
case REACT_PROFILER_TYPE:
|
||||
return "Profiler";
|
||||
|
||||
case REACT_STRICT_MODE_TYPE:
|
||||
return 'StrictMode';
|
||||
|
||||
case REACT_SUSPENSE_TYPE:
|
||||
return 'Suspense';
|
||||
|
||||
case REACT_SUSPENSE_LIST_TYPE:
|
||||
return 'SuspenseList';
|
||||
}
|
||||
|
||||
if (typeof type === 'object') {
|
||||
switch (type.$$typeof) {
|
||||
case REACT_CONTEXT_TYPE:
|
||||
return 'Context.Consumer';
|
||||
|
||||
case REACT_PROVIDER_TYPE:
|
||||
return 'Context.Provider';
|
||||
|
||||
case REACT_FORWARD_REF_TYPE:
|
||||
return getWrappedName(type, type.render, 'ForwardRef');
|
||||
|
||||
case REACT_MEMO_TYPE:
|
||||
return getComponentName(type.type);
|
||||
|
||||
case REACT_BLOCK_TYPE:
|
||||
return getComponentName(type.render);
|
||||
|
||||
case REACT_LAZY_TYPE:
|
||||
{
|
||||
var thenable = type;
|
||||
var resolvedThenable = refineResolvedLazyComponent(thenable);
|
||||
|
||||
if (resolvedThenable) {
|
||||
return getComponentName(resolvedThenable);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
var loggedTypeFailures = {};
|
||||
var currentlyValidatingElement = null;
|
||||
|
||||
function setCurrentlyValidatingElement(element) {
|
||||
{
|
||||
currentlyValidatingElement = element;
|
||||
}
|
||||
}
|
||||
|
||||
function checkPropTypes(typeSpecs, values, location, componentName, element) {
|
||||
{
|
||||
// $FlowFixMe This is okay but Flow doesn't know it.
|
||||
var has = Function.call.bind(Object.prototype.hasOwnProperty);
|
||||
|
||||
for (var typeSpecName in typeSpecs) {
|
||||
if (has(typeSpecs, typeSpecName)) {
|
||||
var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
|
||||
// fail the render phase where it didn't fail before. So we log it.
|
||||
// After these have been cleaned up, we'll let them throw.
|
||||
|
||||
try {
|
||||
// This is intentionally an invariant that gets caught. It's the same
|
||||
// behavior as without this statement except with a better message.
|
||||
if (typeof typeSpecs[typeSpecName] !== 'function') {
|
||||
var err = Error((componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.');
|
||||
err.name = 'Invariant Violation';
|
||||
throw err;
|
||||
}
|
||||
|
||||
error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
|
||||
} catch (ex) {
|
||||
error$1 = ex;
|
||||
}
|
||||
|
||||
if (error$1 && !(error$1 instanceof Error)) {
|
||||
setCurrentlyValidatingElement(element);
|
||||
|
||||
error('%s: type specification of %s' + ' `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error$1);
|
||||
|
||||
setCurrentlyValidatingElement(null);
|
||||
}
|
||||
|
||||
if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
|
||||
// Only monitor this failure once because there tends to be a lot of the
|
||||
// same error.
|
||||
loggedTypeFailures[error$1.message] = true;
|
||||
setCurrentlyValidatingElement(element);
|
||||
|
||||
error('Failed %s type: %s', location, error$1.message);
|
||||
|
||||
setCurrentlyValidatingElement(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ReactCurrentOwner = require('react/lib/ReactCurrentOwner');
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
var RESERVED_PROPS = {
|
||||
key: true,
|
||||
ref: true,
|
||||
__self: true,
|
||||
__source: true
|
||||
};
|
||||
var specialPropKeyWarningShown;
|
||||
var specialPropRefWarningShown;
|
||||
var didWarnAboutStringRefs;
|
||||
|
||||
{
|
||||
didWarnAboutStringRefs = {};
|
||||
}
|
||||
|
||||
function hasValidRef(config) {
|
||||
{
|
||||
if (hasOwnProperty.call(config, 'ref')) {
|
||||
var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
|
||||
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return config.ref !== undefined;
|
||||
}
|
||||
|
||||
function hasValidKey(config) {
|
||||
{
|
||||
if (hasOwnProperty.call(config, 'key')) {
|
||||
var getter = Object.getOwnPropertyDescriptor(config, 'key').get;
|
||||
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return config.key !== undefined;
|
||||
}
|
||||
|
||||
function defineKeyPropWarningGetter(props, displayName) {
|
||||
{
|
||||
var warnAboutAccessingKey = function () {
|
||||
if (!specialPropKeyWarningShown) {
|
||||
specialPropKeyWarningShown = true;
|
||||
|
||||
error('%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);
|
||||
}
|
||||
};
|
||||
|
||||
warnAboutAccessingKey.isReactWarning = true;
|
||||
Object.defineProperty(props, 'key', {
|
||||
get: warnAboutAccessingKey,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function defineRefPropWarningGetter(props, displayName) {
|
||||
{
|
||||
var warnAboutAccessingRef = function () {
|
||||
if (!specialPropRefWarningShown) {
|
||||
specialPropRefWarningShown = true;
|
||||
|
||||
error('%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);
|
||||
}
|
||||
};
|
||||
|
||||
warnAboutAccessingRef.isReactWarning = true;
|
||||
Object.defineProperty(props, 'ref', {
|
||||
get: warnAboutAccessingRef,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Factory method to create a new React element. This no longer adheres to
|
||||
* the class pattern, so do not use new to call it. Also, instanceof check
|
||||
* will not work. Instead test $$typeof field against Symbol.for('react.element') to check
|
||||
* if something is a React Element.
|
||||
*
|
||||
* @param {*} type
|
||||
* @param {*} props
|
||||
* @param {*} key
|
||||
* @param {string|object} ref
|
||||
* @param {*} owner
|
||||
* @param {*} self A *temporary* helper to detect places where `this` is
|
||||
* different from the `owner` when React.createElement is called, so that we
|
||||
* can warn. We want to get rid of owner and replace string `ref`s with arrow
|
||||
* functions, and as long as `this` and owner are the same, there will be no
|
||||
* change in behavior.
|
||||
* @param {*} source An annotation object (added by a transpiler or otherwise)
|
||||
* indicating filename, line number, and/or other information.
|
||||
* @internal
|
||||
*/
|
||||
|
||||
|
||||
var ReactElement = function (type, key, ref, self, source, owner, props) {
|
||||
var element = {
|
||||
// This tag allows us to uniquely identify this as a React Element
|
||||
$$typeof: REACT_ELEMENT_TYPE,
|
||||
// Built-in properties that belong on the element
|
||||
type: type,
|
||||
key: key,
|
||||
ref: ref,
|
||||
props: props,
|
||||
// Record the component responsible for creating this element.
|
||||
_owner: owner
|
||||
};
|
||||
|
||||
{
|
||||
// The validation flag is currently mutative. We put it on
|
||||
// an external backing store so that we can freeze the whole object.
|
||||
// This can be replaced with a WeakMap once they are implemented in
|
||||
// commonly used development environments.
|
||||
element._store = {}; // To make comparing ReactElements easier for testing purposes, we make
|
||||
// the validation flag non-enumerable (where possible, which should
|
||||
// include every environment we run tests in), so the test framework
|
||||
// ignores it.
|
||||
|
||||
Object.defineProperty(element._store, 'validated', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
value: false
|
||||
}); // self and source are DEV only properties.
|
||||
|
||||
Object.defineProperty(element, '_self', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: self
|
||||
}); // Two elements created in two different places should be considered
|
||||
// equal for testing purposes and therefore we hide it from enumeration.
|
||||
|
||||
Object.defineProperty(element, '_source', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: source
|
||||
});
|
||||
|
||||
if (Object.freeze) {
|
||||
Object.freeze(element.props);
|
||||
Object.freeze(element);
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
};
|
||||
/**
|
||||
* https://github.com/reactjs/rfcs/pull/107
|
||||
* @param {*} type
|
||||
* @param {object} props
|
||||
* @param {string} key
|
||||
*/
|
||||
|
||||
function jsxDEV(type, config, maybeKey, source, self) {
|
||||
{
|
||||
var propName; // Reserved names are extracted
|
||||
|
||||
var props = {};
|
||||
var key = null;
|
||||
var ref = null; // Currently, key can be spread in as a prop. This causes a potential
|
||||
// issue if key is also explicitly declared (ie. <div {...props} key="Hi" />
|
||||
// or <div key="Hi" {...props} /> ). We want to deprecate key spread,
|
||||
// but as an intermediary step, we will use jsxDEV for everything except
|
||||
// <div {...props} key="Hi" />, because we aren't currently able to tell if
|
||||
// key is explicitly declared to be undefined or not.
|
||||
|
||||
if (maybeKey !== undefined) {
|
||||
key = '' + maybeKey;
|
||||
}
|
||||
|
||||
if (hasValidKey(config)) {
|
||||
key = '' + config.key;
|
||||
}
|
||||
|
||||
if (hasValidRef(config)) {
|
||||
ref = config.ref;
|
||||
} // Remaining properties are added to a new props object
|
||||
|
||||
|
||||
for (propName in config) {
|
||||
if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
|
||||
props[propName] = config[propName];
|
||||
}
|
||||
} // Resolve default props
|
||||
|
||||
|
||||
if (type && type.defaultProps) {
|
||||
var defaultProps = type.defaultProps;
|
||||
|
||||
for (propName in defaultProps) {
|
||||
if (props[propName] === undefined) {
|
||||
props[propName] = defaultProps[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (key || ref) {
|
||||
var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type;
|
||||
|
||||
if (key) {
|
||||
defineKeyPropWarningGetter(props, displayName);
|
||||
}
|
||||
|
||||
if (ref) {
|
||||
defineRefPropWarningGetter(props, displayName);
|
||||
}
|
||||
}
|
||||
|
||||
return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
|
||||
}
|
||||
}
|
||||
|
||||
var ReactCurrentOwner$1 = require('react/lib/ReactCurrentOwner');
|
||||
|
||||
function setCurrentlyValidatingElement$1(element) {
|
||||
currentlyValidatingElement = element;
|
||||
}
|
||||
|
||||
var propTypesMisspellWarningShown;
|
||||
|
||||
{
|
||||
propTypesMisspellWarningShown = false;
|
||||
}
|
||||
/**
|
||||
* Verifies the object is a ReactElement.
|
||||
* See https://reactjs.org/docs/react-api.html#isvalidelement
|
||||
* @param {?object} object
|
||||
* @return {boolean} True if `object` is a ReactElement.
|
||||
* @final
|
||||
*/
|
||||
|
||||
function isValidElement(object) {
|
||||
{
|
||||
return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
function getDeclarationErrorAddendum() {
|
||||
{
|
||||
if (ReactCurrentOwner$1.current) {
|
||||
var name = ReactCurrentOwner$1.current.getName();
|
||||
|
||||
if (name) {
|
||||
return '\n\nCheck the render method of `' + name + '`.';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceInfoErrorAddendum(source) {
|
||||
{
|
||||
if (source !== undefined) {
|
||||
var fileName = source.fileName.replace(/^.*[\\\/]/, '');
|
||||
var lineNumber = source.lineNumber;
|
||||
return '\n\nCheck your code at ' + fileName + ':' + lineNumber + '.';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Warn if there's no key explicitly set on dynamic arrays of children or
|
||||
* object keys are not valid. This allows us to keep track of children between
|
||||
* updates.
|
||||
*/
|
||||
|
||||
|
||||
var ownerHasKeyUseWarning = {};
|
||||
|
||||
function getCurrentComponentErrorInfo(parentType) {
|
||||
{
|
||||
var info = getDeclarationErrorAddendum();
|
||||
|
||||
if (!info) {
|
||||
var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;
|
||||
|
||||
if (parentName) {
|
||||
info = "\n\nCheck the top-level render call using <" + parentName + ">.";
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Warn if the element doesn't have an explicit key assigned to it.
|
||||
* This element is in an array. The array could grow and shrink or be
|
||||
* reordered. All children that haven't already been validated are required to
|
||||
* have a "key" property assigned to it. Error statuses are cached so a warning
|
||||
* will only be shown once.
|
||||
*
|
||||
* @internal
|
||||
* @param {ReactElement} element Element that requires a key.
|
||||
* @param {*} parentType element's parent's type.
|
||||
*/
|
||||
|
||||
|
||||
function validateExplicitKey(element, parentType) {
|
||||
{
|
||||
if (!element._store || element._store.validated || element.key != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
element._store.validated = true;
|
||||
var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType);
|
||||
|
||||
if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
|
||||
return;
|
||||
}
|
||||
|
||||
ownerHasKeyUseWarning[currentComponentErrorInfo] = true; // Usually the current owner is the offender, but if it accepts children as a
|
||||
// property, it may be the creator of the child that's responsible for
|
||||
// assigning it a key.
|
||||
|
||||
var childOwner = '';
|
||||
|
||||
if (element && element._owner && element._owner !== ReactCurrentOwner$1.current) {
|
||||
// Give the component that originally created this child.
|
||||
childOwner = " It was passed a child from " + element._owner.getName() + ".";
|
||||
}
|
||||
|
||||
setCurrentlyValidatingElement$1(element);
|
||||
|
||||
error('Each child in a list should have a unique "key" prop.' + '%s%s See https://reactjs.org/link/warning-keys for more information.', currentComponentErrorInfo, childOwner);
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Ensure that every element either is passed in a static location, in an
|
||||
* array with an explicit keys property defined, or in an object literal
|
||||
* with valid key property.
|
||||
*
|
||||
* @internal
|
||||
* @param {ReactNode} node Statically passed child of any type.
|
||||
* @param {*} parentType node's parent's type.
|
||||
*/
|
||||
|
||||
|
||||
function validateChildKeys(node, parentType) {
|
||||
{
|
||||
if (typeof node !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.isArray(node)) {
|
||||
for (var i = 0; i < node.length; i++) {
|
||||
var child = node[i];
|
||||
|
||||
if (isValidElement(child)) {
|
||||
validateExplicitKey(child, parentType);
|
||||
}
|
||||
}
|
||||
} else if (isValidElement(node)) {
|
||||
// This element was passed in a valid location.
|
||||
if (node._store) {
|
||||
node._store.validated = true;
|
||||
}
|
||||
} else if (node) {
|
||||
var iteratorFn = getIteratorFn(node);
|
||||
|
||||
if (typeof iteratorFn === 'function') {
|
||||
// Entry iterators used to provide implicit keys,
|
||||
// but now we print a separate warning for them later.
|
||||
if (iteratorFn !== node.entries) {
|
||||
var iterator = iteratorFn.call(node);
|
||||
var step;
|
||||
|
||||
while (!(step = iterator.next()).done) {
|
||||
if (isValidElement(step.value)) {
|
||||
validateExplicitKey(step.value, parentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Given an element, validate that its props follow the propTypes definition,
|
||||
* provided by the type.
|
||||
*
|
||||
* @param {ReactElement} element
|
||||
*/
|
||||
|
||||
|
||||
function validatePropTypes(element) {
|
||||
{
|
||||
var type = element.type;
|
||||
|
||||
if (type === null || type === undefined || typeof type === 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
var propTypes;
|
||||
|
||||
if (typeof type === 'function') {
|
||||
propTypes = type.propTypes;
|
||||
} else if (typeof type === 'object' && (type.$$typeof === REACT_FORWARD_REF_TYPE || // Note: Memo only checks outer props here.
|
||||
// Inner props are checked in the reconciler.
|
||||
type.$$typeof === REACT_MEMO_TYPE)) {
|
||||
propTypes = type.propTypes;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (propTypes) {
|
||||
// Intentionally inside to avoid triggering lazy initializers:
|
||||
var name = getComponentName(type);
|
||||
checkPropTypes(propTypes, element.props, 'prop', name, element);
|
||||
} else if (type.PropTypes !== undefined && !propTypesMisspellWarningShown) {
|
||||
propTypesMisspellWarningShown = true; // Intentionally inside to avoid triggering lazy initializers:
|
||||
|
||||
var _name = getComponentName(type);
|
||||
|
||||
error('Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?', _name || 'Unknown');
|
||||
}
|
||||
|
||||
if (typeof type.getDefaultProps === 'function' && !type.getDefaultProps.isReactClassApproved) {
|
||||
error('getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.');
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Given a fragment, validate that it can only be provided with fragment props
|
||||
* @param {ReactElement} fragment
|
||||
*/
|
||||
|
||||
|
||||
function validateFragmentProps(fragment) {
|
||||
{
|
||||
var keys = Object.keys(fragment.props);
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
|
||||
if (key !== 'children' && key !== 'key') {
|
||||
setCurrentlyValidatingElement$1(fragment);
|
||||
|
||||
error('Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key);
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fragment.ref !== null) {
|
||||
setCurrentlyValidatingElement$1(fragment);
|
||||
|
||||
error('Invalid attribute `ref` supplied to `React.Fragment`.');
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function jsxWithValidation(type, props, key, isStaticChildren, source, self) {
|
||||
{
|
||||
var validType = isValidElementType(type); // We warn in this case but don't throw. We expect the element creation to
|
||||
// succeed and there will likely be errors in render.
|
||||
|
||||
if (!validType) {
|
||||
var info = '';
|
||||
|
||||
if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
|
||||
info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and named imports.";
|
||||
}
|
||||
|
||||
var sourceInfo = getSourceInfoErrorAddendum(source);
|
||||
|
||||
if (sourceInfo) {
|
||||
info += sourceInfo;
|
||||
} else {
|
||||
info += getDeclarationErrorAddendum();
|
||||
}
|
||||
|
||||
var typeString;
|
||||
|
||||
if (type === null) {
|
||||
typeString = 'null';
|
||||
} else if (Array.isArray(type)) {
|
||||
typeString = 'array';
|
||||
} else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {
|
||||
typeString = "<" + (getComponentName(type.type) || 'Unknown') + " />";
|
||||
info = ' Did you accidentally export a JSX literal instead of a component?';
|
||||
} else {
|
||||
typeString = typeof type;
|
||||
}
|
||||
|
||||
error('React.jsx: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', typeString, info);
|
||||
}
|
||||
|
||||
var element = jsxDEV(type, props, key, source, self); // The result can be nullish if a mock or a custom function is used.
|
||||
// TODO: Drop this when these are no longer allowed as the type argument.
|
||||
|
||||
if (element == null) {
|
||||
return element;
|
||||
} // Skip key warning if the type isn't valid since our key validation logic
|
||||
// doesn't expect a non-string/function type and can throw confusing errors.
|
||||
// We don't want exception behavior to differ between dev and prod.
|
||||
// (Rendering will throw with a helpful message and as soon as the type is
|
||||
// fixed, the key warnings will appear.)
|
||||
|
||||
|
||||
if (validType) {
|
||||
var children = props.children;
|
||||
|
||||
if (children !== undefined) {
|
||||
if (isStaticChildren) {
|
||||
if (Array.isArray(children)) {
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
validateChildKeys(children[i], type);
|
||||
}
|
||||
|
||||
if (Object.freeze) {
|
||||
Object.freeze(children);
|
||||
}
|
||||
} else {
|
||||
error('React.jsx: Static children should always be an array. ' + 'You are likely explicitly calling React.jsxs or React.jsxDEV. ' + 'Use the Babel transform instead.');
|
||||
}
|
||||
} else {
|
||||
validateChildKeys(children, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type === exports.Fragment) {
|
||||
validateFragmentProps(element);
|
||||
} else {
|
||||
validatePropTypes(element);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
} // These two functions exist to still get child warnings in dev
|
||||
// even with the prod transform. This means that jsxDEV is purely
|
||||
// opt-in behavior for better messages but that we won't stop
|
||||
// giving you warnings if you use production apis.
|
||||
|
||||
function jsxWithValidationStatic(type, props, key) {
|
||||
{
|
||||
return jsxWithValidation(type, props, key, true);
|
||||
}
|
||||
}
|
||||
function jsxWithValidationDynamic(type, props, key) {
|
||||
{
|
||||
return jsxWithValidation(type, props, key, false);
|
||||
}
|
||||
}
|
||||
|
||||
var jsx = jsxWithValidationDynamic ; // we may want to special case jsxs internally to take advantage of static children.
|
||||
// for now we can ship identical prod functions
|
||||
|
||||
var jsxs = jsxWithValidationStatic ;
|
||||
|
||||
exports.jsx = jsx;
|
||||
exports.jsxs = jsxs;
|
||||
})();
|
||||
}
|
||||
10
fixtures/legacy-jsx-runtimes/react-14/cjs/react-jsx-runtime.production.min.js
vendored
Normal file
10
fixtures/legacy-jsx-runtimes/react-14/cjs/react-jsx-runtime.production.min.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/** @license React v0.14.10
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
'use strict';var f=require("react"),g=60103;exports.Fragment=60107;if("function"===typeof Symbol&&Symbol.for){var h=Symbol.for;g=h("react.element");exports.Fragment=h("react.fragment")}var m=require("react/lib/ReactCurrentOwner"),n=Object.prototype.hasOwnProperty,p={key:!0,ref:!0,__self:!0,__source:!0};
|
||||
function q(c,a,k){var b,d={},e=null,l=null;void 0!==k&&(e=""+k);void 0!==a.key&&(e=""+a.key);void 0!==a.ref&&(l=a.ref);for(b in a)n.call(a,b)&&!p.hasOwnProperty(b)&&(d[b]=a[b]);if(c&&c.defaultProps)for(b in a=c.defaultProps,a)void 0===d[b]&&(d[b]=a[b]);return{$$typeof:g,type:c,key:e,ref:l,props:d,_owner:m.current}}exports.jsx=q;exports.jsxs=q;
|
||||
7
fixtures/legacy-jsx-runtimes/react-14/jsx-dev-runtime.js
vendored
Normal file
7
fixtures/legacy-jsx-runtimes/react-14/jsx-dev-runtime.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-jsx-dev-runtime.production.min.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-jsx-dev-runtime.development.js');
|
||||
}
|
||||
7
fixtures/legacy-jsx-runtimes/react-14/jsx-runtime.js
vendored
Normal file
7
fixtures/legacy-jsx-runtimes/react-14/jsx-runtime.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-jsx-runtime.production.min.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-jsx-runtime.development.js');
|
||||
}
|
||||
6
fixtures/legacy-jsx-runtimes/react-14/package.json
Normal file
6
fixtures/legacy-jsx-runtimes/react-14/package.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "0.14",
|
||||
"react-dom": "0.14"
|
||||
}
|
||||
}
|
||||
780
fixtures/legacy-jsx-runtimes/react-14/react-14.test.js
Normal file
780
fixtures/legacy-jsx-runtimes/react-14/react-14.test.js
Normal file
@@ -0,0 +1,780 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails react-core
|
||||
*/
|
||||
|
||||
// These tests are based on ReactJSXElement-test,
|
||||
// ReactJSXElementValidator-test, ReactComponent-test,
|
||||
// and ReactElementJSX-test.
|
||||
|
||||
jest.mock('react/jsx-runtime', () => require('./jsx-runtime'), {virtual: true});
|
||||
jest.mock('react/jsx-dev-runtime', () => require('./jsx-dev-runtime'), {
|
||||
virtual: true,
|
||||
});
|
||||
|
||||
let React = require('react');
|
||||
let ReactDOM = require('react-dom');
|
||||
let ReactTestUtils = {
|
||||
renderIntoDocument(el) {
|
||||
const container = document.createElement('div');
|
||||
return ReactDOM.render(el, container);
|
||||
},
|
||||
};
|
||||
let PropTypes = React.PropTypes;
|
||||
let Component = class Component extends React.Component {
|
||||
render() {
|
||||
return <div />;
|
||||
}
|
||||
};
|
||||
let RequiredPropComponent = class extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
};
|
||||
RequiredPropComponent.displayName = 'RequiredPropComponent';
|
||||
RequiredPropComponent.propTypes = {prop: PropTypes.string.isRequired};
|
||||
|
||||
it('works', () => {
|
||||
const container = document.createElement('div');
|
||||
ReactDOM.render(<h1>hello</h1>, container);
|
||||
expect(container.textContent).toBe('hello');
|
||||
});
|
||||
|
||||
it('returns a complete element according to spec', () => {
|
||||
const element = <Component />;
|
||||
expect(element.type).toBe(Component);
|
||||
expect(element.key).toBe(null);
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('allows a lower-case to be passed as the string type', () => {
|
||||
const element = <div />;
|
||||
expect(element.type).toBe('div');
|
||||
expect(element.key).toBe(null);
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('allows a string to be passed as the type', () => {
|
||||
const TagName = 'div';
|
||||
const element = <TagName />;
|
||||
expect(element.type).toBe('div');
|
||||
expect(element.key).toBe(null);
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('returns an immutable element', () => {
|
||||
const element = <Component />;
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
expect(() => (element.type = 'div')).toThrow();
|
||||
} else {
|
||||
expect(() => (element.type = 'div')).not.toThrow();
|
||||
}
|
||||
});
|
||||
|
||||
it('does not reuse the object that is spread into props', () => {
|
||||
const config = {foo: 1};
|
||||
const element = <Component {...config} />;
|
||||
expect(element.props.foo).toBe(1);
|
||||
config.foo = 2;
|
||||
expect(element.props.foo).toBe(1);
|
||||
});
|
||||
|
||||
it('extracts key and ref from the rest of the props', () => {
|
||||
const element = <Component key="12" ref="34" foo="56" />;
|
||||
expect(element.type).toBe(Component);
|
||||
expect(element.key).toBe('12');
|
||||
expect(element.ref).toBe('34');
|
||||
const expectation = {foo: '56'};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('coerces the key to a string', () => {
|
||||
const element = <Component key={12} foo="56" />;
|
||||
expect(element.type).toBe(Component);
|
||||
expect(element.key).toBe('12');
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {foo: '56'};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('merges JSX children onto the children prop', () => {
|
||||
const a = 1;
|
||||
const element = <Component children="text">{a}</Component>;
|
||||
expect(element.props.children).toBe(a);
|
||||
});
|
||||
|
||||
it('does not override children if no JSX children are provided', () => {
|
||||
const element = <Component children="text" />;
|
||||
expect(element.props.children).toBe('text');
|
||||
});
|
||||
|
||||
it('overrides children if null is provided as a JSX child', () => {
|
||||
const element = <Component children="text">{null}</Component>;
|
||||
expect(element.props.children).toBe(null);
|
||||
});
|
||||
|
||||
it('overrides children if undefined is provided as an argument', () => {
|
||||
const element = <Component children="text">{undefined}</Component>;
|
||||
expect(element.props.children).toBe(undefined);
|
||||
|
||||
const element2 = React.cloneElement(
|
||||
<Component children="text" />,
|
||||
{},
|
||||
undefined
|
||||
);
|
||||
expect(element2.props.children).toBe(undefined);
|
||||
});
|
||||
|
||||
it('merges JSX children onto the children prop in an array', () => {
|
||||
const a = 1;
|
||||
const b = 2;
|
||||
const c = 3;
|
||||
const element = (
|
||||
<Component>
|
||||
{a}
|
||||
{b}
|
||||
{c}
|
||||
</Component>
|
||||
);
|
||||
expect(element.props.children).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it('allows static methods to be called using the type property', () => {
|
||||
class StaticMethodComponent {
|
||||
static someStaticMethod() {
|
||||
return 'someReturnValue';
|
||||
}
|
||||
render() {
|
||||
return <div />;
|
||||
}
|
||||
}
|
||||
|
||||
const element = <StaticMethodComponent />;
|
||||
expect(element.type.someStaticMethod()).toBe('someReturnValue');
|
||||
});
|
||||
|
||||
it('identifies valid elements', () => {
|
||||
expect(React.isValidElement(<div />)).toEqual(true);
|
||||
expect(React.isValidElement(<Component />)).toEqual(true);
|
||||
|
||||
expect(React.isValidElement(null)).toEqual(false);
|
||||
expect(React.isValidElement(true)).toEqual(false);
|
||||
expect(React.isValidElement({})).toEqual(false);
|
||||
expect(React.isValidElement('string')).toEqual(false);
|
||||
expect(React.isValidElement(Component)).toEqual(false);
|
||||
expect(React.isValidElement({type: 'div', props: {}})).toEqual(false);
|
||||
});
|
||||
|
||||
it('is indistinguishable from a plain object', () => {
|
||||
const element = <div className="foo" />;
|
||||
const object = {};
|
||||
expect(element.constructor).toBe(object.constructor);
|
||||
});
|
||||
|
||||
it('should use default prop value when removing a prop', () => {
|
||||
Component.defaultProps = {fruit: 'persimmon'};
|
||||
|
||||
const container = document.createElement('div');
|
||||
const instance = ReactDOM.render(<Component fruit="mango" />, container);
|
||||
expect(instance.props.fruit).toBe('mango');
|
||||
|
||||
ReactDOM.render(<Component />, container);
|
||||
expect(instance.props.fruit).toBe('persimmon');
|
||||
});
|
||||
|
||||
it('should normalize props with default values', () => {
|
||||
class NormalizingComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
NormalizingComponent.defaultProps = {prop: 'testKey'};
|
||||
|
||||
const container = document.createElement('div');
|
||||
const instance = ReactDOM.render(<NormalizingComponent />, container);
|
||||
expect(instance.props.prop).toBe('testKey');
|
||||
|
||||
const inst2 = ReactDOM.render(
|
||||
<NormalizingComponent prop={null} />,
|
||||
container
|
||||
);
|
||||
expect(inst2.props.prop).toBe(null);
|
||||
});
|
||||
|
||||
it('warns for keys for arrays of elements in children position', () => {
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<Component>{[<Component />, <Component />]}</Component>
|
||||
)
|
||||
).toErrorDev('Each child in a list should have a unique "key" prop.', {
|
||||
withoutStack: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('warns for keys for arrays of elements with owner info', () => {
|
||||
class InnerComponent extends React.Component {
|
||||
render() {
|
||||
return <Component>{this.props.childSet}</Component>;
|
||||
}
|
||||
}
|
||||
|
||||
class ComponentWrapper extends React.Component {
|
||||
render() {
|
||||
return <InnerComponent childSet={[<Component />, <Component />]} />;
|
||||
}
|
||||
}
|
||||
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<ComponentWrapper />)
|
||||
).toErrorDev(
|
||||
'Each child in a list should have a unique "key" prop.' +
|
||||
'\n\nCheck the render method of `InnerComponent`. ' +
|
||||
'It was passed a child from ComponentWrapper. ',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warn for arrays of elements with keys', () => {
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<Component>{[<Component key="#1" />, <Component key="#2" />]}</Component>
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warn for iterable elements with keys', () => {
|
||||
const iterable = {
|
||||
'@@iterator': function() {
|
||||
let i = 0;
|
||||
return {
|
||||
next: function() {
|
||||
const done = ++i > 2;
|
||||
return {
|
||||
value: done ? undefined : <Component key={'#' + i} />,
|
||||
done: done,
|
||||
};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component>{iterable}</Component>);
|
||||
});
|
||||
|
||||
it('does not warn for numeric keys in entry iterable as a child', () => {
|
||||
const iterable = {
|
||||
'@@iterator': function() {
|
||||
let i = 0;
|
||||
return {
|
||||
next: function() {
|
||||
const done = ++i > 2;
|
||||
return {value: done ? undefined : [i, <Component />], done: done};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
iterable.entries = iterable['@@iterator'];
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component>{iterable}</Component>);
|
||||
});
|
||||
|
||||
it('does not warn when the element is directly as children', () => {
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<Component>
|
||||
<Component />
|
||||
<Component />
|
||||
</Component>
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warn when the child array contains non-elements', () => {
|
||||
void (<Component>{[{}, {}]}</Component>);
|
||||
});
|
||||
|
||||
it('should give context for PropType errors in nested components.', () => {
|
||||
// In this test, we're making sure that if a proptype error is found in a
|
||||
// component, we give a small hint as to which parent instantiated that
|
||||
// component as per warnings about key usage in ReactElementValidator.
|
||||
function MyComp({color}) {
|
||||
return <div>My color is {color}</div>;
|
||||
}
|
||||
MyComp.propTypes = {
|
||||
color: PropTypes.string,
|
||||
};
|
||||
class ParentComp extends React.Component {
|
||||
render() {
|
||||
return <MyComp color={123} />;
|
||||
}
|
||||
}
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<ParentComp />)
|
||||
).toErrorDev(
|
||||
'Warning: Failed prop type: ' +
|
||||
'Invalid prop `color` of type `number` supplied to `MyComp`, ' +
|
||||
'expected `string`.',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
it('gives a helpful error when passing null, undefined, or boolean', () => {
|
||||
const Undefined = undefined;
|
||||
const Null = null;
|
||||
const True = true;
|
||||
const Div = 'div';
|
||||
expect(
|
||||
() => void (<Undefined />)
|
||||
).toErrorDev(
|
||||
'Warning: React.jsx: type is invalid -- expected a string ' +
|
||||
'(for built-in components) or a class/function (for composite ' +
|
||||
'components) but got: undefined. You likely forgot to export your ' +
|
||||
"component from the file it's defined in, or you might have mixed up " +
|
||||
'default and named imports.' +
|
||||
(process.env.BABEL_ENV === 'development'
|
||||
? '\n\nCheck your code at **.'
|
||||
: ''),
|
||||
{withoutStack: true}
|
||||
);
|
||||
expect(
|
||||
() => void (<Null />)
|
||||
).toErrorDev(
|
||||
'Warning: React.jsx: type is invalid -- expected a string ' +
|
||||
'(for built-in components) or a class/function (for composite ' +
|
||||
'components) but got: null.' +
|
||||
(process.env.BABEL_ENV === 'development'
|
||||
? '\n\nCheck your code at **.'
|
||||
: ''),
|
||||
{withoutStack: true}
|
||||
);
|
||||
expect(
|
||||
() => void (<True />)
|
||||
).toErrorDev(
|
||||
'Warning: React.jsx: type is invalid -- expected a string ' +
|
||||
'(for built-in components) or a class/function (for composite ' +
|
||||
'components) but got: boolean.' +
|
||||
(process.env.BABEL_ENV === 'development'
|
||||
? '\n\nCheck your code at **.'
|
||||
: ''),
|
||||
{withoutStack: true}
|
||||
);
|
||||
// No error expected
|
||||
void (<Div />);
|
||||
});
|
||||
|
||||
it('should check default prop values', () => {
|
||||
RequiredPropComponent.defaultProps = {prop: null};
|
||||
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<RequiredPropComponent />)
|
||||
).toErrorDev(
|
||||
'Warning: Failed prop type: Required prop `prop` was not specified in ' +
|
||||
'`RequiredPropComponent`.',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn on invalid prop types', () => {
|
||||
// Since there is no prevalidation step for ES6 classes, there is no hook
|
||||
// for us to issue a warning earlier than element creation when the error
|
||||
// actually occurs. Since this step is skipped in production, we should just
|
||||
// warn instead of throwing for this case.
|
||||
class NullPropTypeComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
NullPropTypeComponent.propTypes = {
|
||||
prop: null,
|
||||
};
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<NullPropTypeComponent />)
|
||||
).toErrorDev(
|
||||
'NullPropTypeComponent: prop type `prop` is invalid; it must be a ' +
|
||||
'function, usually from the `prop-types` package,',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
xit('should warn on invalid context types', () => {
|
||||
class NullContextTypeComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
NullContextTypeComponent.contextTypes = {
|
||||
prop: null,
|
||||
};
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<NullContextTypeComponent />)
|
||||
).toErrorDev(
|
||||
'NullContextTypeComponent: type `prop` is invalid; it must ' +
|
||||
'be a function, usually from the `prop-types` package,'
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn if getDefaultProps is specified on the class', () => {
|
||||
class GetDefaultPropsComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
GetDefaultPropsComponent.getDefaultProps = () => ({
|
||||
prop: 'foo',
|
||||
});
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<GetDefaultPropsComponent />)
|
||||
).toErrorDev(
|
||||
'getDefaultProps is only used on classic React.createClass definitions.' +
|
||||
' Use a static property named `defaultProps` instead.',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn if component declares PropTypes instead of propTypes', () => {
|
||||
class MisspelledPropTypesComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
MisspelledPropTypesComponent.PropTypes = {
|
||||
prop: PropTypes.string,
|
||||
};
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<MisspelledPropTypesComponent prop="hi" />
|
||||
)
|
||||
).toErrorDev(
|
||||
'Warning: Component MisspelledPropTypesComponent declared `PropTypes` ' +
|
||||
'instead of `propTypes`. Did you misspell the property assignment?',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
// Not supported.
|
||||
xit('warns for fragments with illegal attributes', () => {
|
||||
class Foo extends React.Component {
|
||||
render() {
|
||||
return <React.Fragment a={1}>hello</React.Fragment>;
|
||||
}
|
||||
}
|
||||
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<Foo />)).toErrorDev(
|
||||
'Invalid prop `a` supplied to `React.Fragment`. React.Fragment ' +
|
||||
'can only have `key` and `children` props.'
|
||||
);
|
||||
});
|
||||
|
||||
// Not supported.
|
||||
xit('warns for fragments with refs', () => {
|
||||
class Foo extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<React.Fragment
|
||||
ref={bar => {
|
||||
this.foo = bar;
|
||||
}}>
|
||||
hello
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<Foo />)).toErrorDev(
|
||||
'Invalid attribute `ref` supplied to `React.Fragment`.'
|
||||
);
|
||||
});
|
||||
|
||||
// Not supported.
|
||||
xit('does not warn for fragments of multiple elements without keys', () => {
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<>
|
||||
<span>1</span>
|
||||
<span>2</span>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
// Not supported.
|
||||
xit('warns for fragments of multiple elements with same key', () => {
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<>
|
||||
<span key="a">1</span>
|
||||
<span key="a">2</span>
|
||||
<span key="b">3</span>
|
||||
</>
|
||||
)
|
||||
).toErrorDev('Encountered two children with the same key, `a`.', {
|
||||
withoutStack: true,
|
||||
});
|
||||
});
|
||||
|
||||
// Not supported.
|
||||
xit('does not call lazy initializers eagerly', () => {
|
||||
let didCall = false;
|
||||
const Lazy = React.lazy(() => {
|
||||
didCall = true;
|
||||
return {then() {}};
|
||||
});
|
||||
<Lazy />;
|
||||
expect(didCall).toBe(false);
|
||||
});
|
||||
|
||||
it('supports classic refs', () => {
|
||||
class Foo extends React.Component {
|
||||
render() {
|
||||
return <div className="foo" ref="inner" />;
|
||||
}
|
||||
}
|
||||
const container = document.createElement('div');
|
||||
const instance = ReactDOM.render(<Foo />, container);
|
||||
expect(instance.refs.inner.className).toBe('foo');
|
||||
});
|
||||
|
||||
it('should support refs on owned components', () => {
|
||||
const innerObj = {};
|
||||
const outerObj = {};
|
||||
|
||||
class Wrapper extends React.Component {
|
||||
getObject = () => {
|
||||
return this.props.object;
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
class Component extends React.Component {
|
||||
render() {
|
||||
const inner = <Wrapper object={innerObj} ref="inner" />;
|
||||
const outer = (
|
||||
<Wrapper object={outerObj} ref="outer">
|
||||
{inner}
|
||||
</Wrapper>
|
||||
);
|
||||
return outer;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
expect(this.refs.inner.getObject()).toEqual(innerObj);
|
||||
expect(this.refs.outer.getObject()).toEqual(outerObj);
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
});
|
||||
|
||||
it('should support callback-style refs', () => {
|
||||
const innerObj = {};
|
||||
const outerObj = {};
|
||||
|
||||
class Wrapper extends React.Component {
|
||||
getObject = () => {
|
||||
return this.props.object;
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
let mounted = false;
|
||||
|
||||
class Component extends React.Component {
|
||||
render() {
|
||||
const inner = (
|
||||
<Wrapper object={innerObj} ref={c => (this.innerRef = c)} />
|
||||
);
|
||||
const outer = (
|
||||
<Wrapper object={outerObj} ref={c => (this.outerRef = c)}>
|
||||
{inner}
|
||||
</Wrapper>
|
||||
);
|
||||
return outer;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
expect(this.innerRef.getObject()).toEqual(innerObj);
|
||||
expect(this.outerRef.getObject()).toEqual(outerObj);
|
||||
mounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
expect(mounted).toBe(true);
|
||||
});
|
||||
|
||||
// Not supported.
|
||||
xit('should support object-style refs', () => {
|
||||
const innerObj = {};
|
||||
const outerObj = {};
|
||||
|
||||
class Wrapper extends React.Component {
|
||||
getObject = () => {
|
||||
return this.props.object;
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
let mounted = false;
|
||||
|
||||
class Component extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.innerRef = React.createRef();
|
||||
this.outerRef = React.createRef();
|
||||
}
|
||||
render() {
|
||||
const inner = <Wrapper object={innerObj} ref={this.innerRef} />;
|
||||
const outer = (
|
||||
<Wrapper object={outerObj} ref={this.outerRef}>
|
||||
{inner}
|
||||
</Wrapper>
|
||||
);
|
||||
return outer;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
expect(this.innerRef.current.getObject()).toEqual(innerObj);
|
||||
expect(this.outerRef.current.getObject()).toEqual(outerObj);
|
||||
mounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
expect(mounted).toBe(true);
|
||||
});
|
||||
|
||||
it('should support new-style refs with mixed-up owners', () => {
|
||||
class Wrapper extends React.Component {
|
||||
getTitle = () => {
|
||||
return this.props.title;
|
||||
};
|
||||
|
||||
render() {
|
||||
return this.props.getContent();
|
||||
}
|
||||
}
|
||||
|
||||
let mounted = false;
|
||||
|
||||
class Component extends React.Component {
|
||||
getInner = () => {
|
||||
// (With old-style refs, it's impossible to get a ref to this div
|
||||
// because Wrapper is the current owner when this function is called.)
|
||||
return <div className="inner" ref={c => (this.innerRef = c)} />;
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Wrapper
|
||||
title="wrapper"
|
||||
ref={c => (this.wrapperRef = c)}
|
||||
getContent={this.getInner}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// Check .props.title to make sure we got the right elements back
|
||||
expect(this.wrapperRef.getTitle()).toBe('wrapper');
|
||||
expect(this.innerRef.className).toBe('inner');
|
||||
mounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
expect(mounted).toBe(true);
|
||||
});
|
||||
|
||||
it('should warn when `key` is being accessed on composite element', () => {
|
||||
const container = document.createElement('div');
|
||||
class Child extends React.Component {
|
||||
render() {
|
||||
return <div> {this.props.key} </div>;
|
||||
}
|
||||
}
|
||||
class Parent extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Child key="0" />
|
||||
<Child key="1" />
|
||||
<Child key="2" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
expect(() =>
|
||||
ReactDOM.render(<Parent />, container)
|
||||
).toErrorDev(
|
||||
'Child: `key` is not a prop. Trying to access it will result ' +
|
||||
'in `undefined` being returned. If you need to access the same ' +
|
||||
'value within the child component, you should pass it as a different ' +
|
||||
'prop. (https://reactjs.org/link/special-props)',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn when `ref` is being accessed', () => {
|
||||
const container = document.createElement('div');
|
||||
class Child extends React.Component {
|
||||
render() {
|
||||
return <div> {this.props.ref} </div>;
|
||||
}
|
||||
}
|
||||
class Parent extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Child ref="childElement" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
expect(() =>
|
||||
ReactDOM.render(<Parent />, container)
|
||||
).toErrorDev(
|
||||
'Child: `ref` is not a prop. Trying to access it will result ' +
|
||||
'in `undefined` being returned. If you need to access the same ' +
|
||||
'value within the child component, you should pass it as a different ' +
|
||||
'prop. (https://reactjs.org/link/special-props)',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
// Note: no warning before 16.
|
||||
it('should NOT warn when owner and self are different for string refs', () => {
|
||||
class ClassWithRenderProp extends React.Component {
|
||||
render() {
|
||||
return this.props.children();
|
||||
}
|
||||
}
|
||||
|
||||
class ClassParent extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<ClassWithRenderProp>{() => <div ref="myRef" />}</ClassWithRenderProp>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const container = document.createElement('div');
|
||||
ReactDOM.render(<ClassParent />, container);
|
||||
});
|
||||
285
fixtures/legacy-jsx-runtimes/react-14/yarn.lock
Normal file
285
fixtures/legacy-jsx-runtimes/react-14/yarn.lock
Normal file
@@ -0,0 +1,285 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
acorn@^5.2.1:
|
||||
version "5.7.4"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e"
|
||||
integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==
|
||||
|
||||
amdefine@>=0.0.4:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
|
||||
integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=
|
||||
|
||||
asap@~2.0.3:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
|
||||
|
||||
ast-types@0.9.6:
|
||||
version "0.9.6"
|
||||
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9"
|
||||
integrity sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
||||
|
||||
base62@^1.1.0:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.yarnpkg.com/base62/-/base62-1.2.8.tgz#1264cb0fb848d875792877479dbe8bae6bae3428"
|
||||
integrity sha512-V6YHUbjLxN1ymqNLb1DPHoU1CpfdL7d2YTIp5W3U4hhoG4hhxNmsFDs66M9EXxBiSEke5Bt5dwdfMwwZF70iLA==
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
commander@^2.5.0:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
|
||||
commoner@^0.10.1:
|
||||
version "0.10.8"
|
||||
resolved "https://registry.yarnpkg.com/commoner/-/commoner-0.10.8.tgz#34fc3672cd24393e8bb47e70caa0293811f4f2c5"
|
||||
integrity sha1-NPw2cs0kOT6LtH5wyqApOBH08sU=
|
||||
dependencies:
|
||||
commander "^2.5.0"
|
||||
detective "^4.3.1"
|
||||
glob "^5.0.15"
|
||||
graceful-fs "^4.1.2"
|
||||
iconv-lite "^0.4.5"
|
||||
mkdirp "^0.5.0"
|
||||
private "^0.1.6"
|
||||
q "^1.1.2"
|
||||
recast "^0.11.17"
|
||||
|
||||
concat-map@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
|
||||
core-js@^1.0.0:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
|
||||
integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=
|
||||
|
||||
defined@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
|
||||
integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=
|
||||
|
||||
detective@^4.3.1:
|
||||
version "4.7.1"
|
||||
resolved "https://registry.yarnpkg.com/detective/-/detective-4.7.1.tgz#0eca7314338442febb6d65da54c10bb1c82b246e"
|
||||
integrity sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==
|
||||
dependencies:
|
||||
acorn "^5.2.1"
|
||||
defined "^1.0.0"
|
||||
|
||||
envify@^3.0.0:
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/envify/-/envify-3.4.1.tgz#d7122329e8df1688ba771b12501917c9ce5cbce8"
|
||||
integrity sha1-1xIjKejfFoi6dxsSUBkXyc5cvOg=
|
||||
dependencies:
|
||||
jstransform "^11.0.3"
|
||||
through "~2.3.4"
|
||||
|
||||
esprima-fb@^15001.1.0-dev-harmony-fb:
|
||||
version "15001.1.0-dev-harmony-fb"
|
||||
resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-15001.1.0-dev-harmony-fb.tgz#30a947303c6b8d5e955bee2b99b1d233206a6901"
|
||||
integrity sha1-MKlHMDxrjV6VW+4rmbHSMyBqaQE=
|
||||
|
||||
esprima@~3.1.0:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
|
||||
integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=
|
||||
|
||||
fbjs@^0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.6.1.tgz#9636b7705f5ba9684d44b72f78321254afc860f7"
|
||||
integrity sha1-lja3cF9bqWhNRLcveDISVK/IYPc=
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
loose-envify "^1.0.0"
|
||||
promise "^7.0.3"
|
||||
ua-parser-js "^0.7.9"
|
||||
whatwg-fetch "^0.9.0"
|
||||
|
||||
glob@^5.0.15:
|
||||
version "5.0.15"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
|
||||
integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=
|
||||
dependencies:
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "2 || 3"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
graceful-fs@^4.1.2:
|
||||
version "4.2.4"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
||||
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
|
||||
|
||||
iconv-lite@^0.4.5:
|
||||
version "0.4.24"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
inflight@^1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
|
||||
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
|
||||
dependencies:
|
||||
once "^1.3.0"
|
||||
wrappy "1"
|
||||
|
||||
inherits@2:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
|
||||
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
jstransform@^11.0.3:
|
||||
version "11.0.3"
|
||||
resolved "https://registry.yarnpkg.com/jstransform/-/jstransform-11.0.3.tgz#09a78993e0ae4d4ef4487f6155a91f6190cb4223"
|
||||
integrity sha1-CaeJk+CuTU70SH9hVakfYZDLQiM=
|
||||
dependencies:
|
||||
base62 "^1.1.0"
|
||||
commoner "^0.10.1"
|
||||
esprima-fb "^15001.1.0-dev-harmony-fb"
|
||||
object-assign "^2.0.0"
|
||||
source-map "^0.4.2"
|
||||
|
||||
loose-envify@^1.0.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||
dependencies:
|
||||
js-tokens "^3.0.0 || ^4.0.0"
|
||||
|
||||
"minimatch@2 || 3":
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||
dependencies:
|
||||
brace-expansion "^1.1.7"
|
||||
|
||||
minimist@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
|
||||
mkdirp@^0.5.0:
|
||||
version "0.5.5"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
||||
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
|
||||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
object-assign@^2.0.0:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa"
|
||||
integrity sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo=
|
||||
|
||||
once@^1.3.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
|
||||
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||
dependencies:
|
||||
wrappy "1"
|
||||
|
||||
path-is-absolute@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
|
||||
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||
|
||||
private@^0.1.6, private@~0.1.5:
|
||||
version "0.1.8"
|
||||
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
|
||||
integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==
|
||||
|
||||
promise@^7.0.3:
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
|
||||
integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
q@^1.1.2:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
|
||||
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
|
||||
|
||||
react-dom@0.14:
|
||||
version "0.14.9"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-0.14.9.tgz#05064a3dcf0fb1880a3b2bfc9d58c55d8d9f6293"
|
||||
integrity sha1-BQZKPc8PsYgKOyv8nVjFXY2fYpM=
|
||||
|
||||
react@0.14:
|
||||
version "0.14.9"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-0.14.9.tgz#9110a6497c49d44ba1c0edd317aec29c2e0d91d1"
|
||||
integrity sha1-kRCmSXxJ1EuhwO3TF67CnC4NkdE=
|
||||
dependencies:
|
||||
envify "^3.0.0"
|
||||
fbjs "^0.6.1"
|
||||
|
||||
recast@^0.11.17:
|
||||
version "0.11.23"
|
||||
resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3"
|
||||
integrity sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=
|
||||
dependencies:
|
||||
ast-types "0.9.6"
|
||||
esprima "~3.1.0"
|
||||
private "~0.1.5"
|
||||
source-map "~0.5.0"
|
||||
|
||||
"safer-buffer@>= 2.1.2 < 3":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
source-map@^0.4.2:
|
||||
version "0.4.4"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b"
|
||||
integrity sha1-66T12pwNyZneaAMti092FzZSA2s=
|
||||
dependencies:
|
||||
amdefine ">=0.0.4"
|
||||
|
||||
source-map@~0.5.0:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
||||
|
||||
through@~2.3.4:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=
|
||||
|
||||
ua-parser-js@^0.7.9:
|
||||
version "0.7.22"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.22.tgz#960df60a5f911ea8f1c818f3747b99c6e177eae3"
|
||||
integrity sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q==
|
||||
|
||||
whatwg-fetch@^0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-0.9.0.tgz#0e3684c6cb9995b43efc9df03e4c365d95fd9cc0"
|
||||
integrity sha1-DjaExsuZlbQ+/J3wPkw2XZX9nMA=
|
||||
|
||||
wrappy@1:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
|
||||
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
@@ -0,0 +1,866 @@
|
||||
/** @license React v15.7.0
|
||||
* react-jsx-dev-runtime.development.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook');
|
||||
|
||||
// ATTENTION
|
||||
// When adding new symbols to this file,
|
||||
// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
|
||||
// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
|
||||
// nor polyfill, then a plain number is used for performance.
|
||||
var REACT_ELEMENT_TYPE = 0xeac7;
|
||||
var REACT_PORTAL_TYPE = 0xeaca;
|
||||
exports.Fragment = 0xeacb;
|
||||
var REACT_STRICT_MODE_TYPE = 0xeacc;
|
||||
var REACT_PROFILER_TYPE = 0xead2;
|
||||
var REACT_PROVIDER_TYPE = 0xeacd;
|
||||
var REACT_CONTEXT_TYPE = 0xeace;
|
||||
var REACT_FORWARD_REF_TYPE = 0xead0;
|
||||
var REACT_SUSPENSE_TYPE = 0xead1;
|
||||
var REACT_SUSPENSE_LIST_TYPE = 0xead8;
|
||||
var REACT_MEMO_TYPE = 0xead3;
|
||||
var REACT_LAZY_TYPE = 0xead4;
|
||||
var REACT_BLOCK_TYPE = 0xead9;
|
||||
var REACT_SERVER_BLOCK_TYPE = 0xeada;
|
||||
var REACT_FUNDAMENTAL_TYPE = 0xead5;
|
||||
var REACT_SCOPE_TYPE = 0xead7;
|
||||
var REACT_OPAQUE_ID_TYPE = 0xeae0;
|
||||
var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1;
|
||||
var REACT_OFFSCREEN_TYPE = 0xeae2;
|
||||
var REACT_LEGACY_HIDDEN_TYPE = 0xeae3;
|
||||
|
||||
if (typeof Symbol === 'function' && Symbol.for) {
|
||||
var symbolFor = Symbol.for;
|
||||
REACT_ELEMENT_TYPE = symbolFor('react.element');
|
||||
REACT_PORTAL_TYPE = symbolFor('react.portal');
|
||||
exports.Fragment = symbolFor('react.fragment');
|
||||
REACT_STRICT_MODE_TYPE = symbolFor('react.strict_mode');
|
||||
REACT_PROFILER_TYPE = symbolFor('react.profiler');
|
||||
REACT_PROVIDER_TYPE = symbolFor('react.provider');
|
||||
REACT_CONTEXT_TYPE = symbolFor('react.context');
|
||||
REACT_FORWARD_REF_TYPE = symbolFor('react.forward_ref');
|
||||
REACT_SUSPENSE_TYPE = symbolFor('react.suspense');
|
||||
REACT_SUSPENSE_LIST_TYPE = symbolFor('react.suspense_list');
|
||||
REACT_MEMO_TYPE = symbolFor('react.memo');
|
||||
REACT_LAZY_TYPE = symbolFor('react.lazy');
|
||||
REACT_BLOCK_TYPE = symbolFor('react.block');
|
||||
REACT_SERVER_BLOCK_TYPE = symbolFor('react.server.block');
|
||||
REACT_FUNDAMENTAL_TYPE = symbolFor('react.fundamental');
|
||||
REACT_SCOPE_TYPE = symbolFor('react.scope');
|
||||
REACT_OPAQUE_ID_TYPE = symbolFor('react.opaque.id');
|
||||
REACT_DEBUG_TRACING_MODE_TYPE = symbolFor('react.debug_trace_mode');
|
||||
REACT_OFFSCREEN_TYPE = symbolFor('react.offscreen');
|
||||
REACT_LEGACY_HIDDEN_TYPE = symbolFor('react.legacy_hidden');
|
||||
}
|
||||
|
||||
var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
|
||||
var FAUX_ITERATOR_SYMBOL = '@@iterator';
|
||||
function getIteratorFn(maybeIterable) {
|
||||
if (maybeIterable === null || typeof maybeIterable !== 'object') {
|
||||
return null;
|
||||
}
|
||||
|
||||
var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
|
||||
|
||||
if (typeof maybeIterator === 'function') {
|
||||
return maybeIterator;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function error(format) {
|
||||
{
|
||||
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
||||
args[_key2 - 1] = arguments[_key2];
|
||||
}
|
||||
|
||||
printWarning('error', format, args);
|
||||
}
|
||||
}
|
||||
|
||||
function printWarning(level, format, args) {
|
||||
// When changing this logic, you might want to also
|
||||
// update consoleWithStackDev.www.js as well.
|
||||
{
|
||||
var stack = '';
|
||||
|
||||
if (currentlyValidatingElement) {
|
||||
stack += ReactComponentTreeHook.getCurrentStackAddendum(currentlyValidatingElement)
|
||||
}
|
||||
|
||||
|
||||
if (stack !== '') {
|
||||
format += '%s';
|
||||
args = args.concat([stack]);
|
||||
}
|
||||
|
||||
var argsWithFormat = args.map(function (item) {
|
||||
return '' + item;
|
||||
}); // Careful: RN currently depends on this prefix
|
||||
|
||||
argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
|
||||
// breaks IE9: https://github.com/facebook/react/issues/13610
|
||||
// eslint-disable-next-line react-internal/no-production-logging
|
||||
|
||||
Function.prototype.apply.call(console[level], console, argsWithFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// Filter certain DOM attributes (e.g. src, href) if their values are empty strings.
|
||||
|
||||
var enableScopeAPI = false; // Experimental Create Event Handle API.
|
||||
|
||||
function isValidElementType(type) {
|
||||
if (typeof type === 'string' || typeof type === 'function') {
|
||||
return true;
|
||||
} // Note: typeof might be other than 'symbol' or 'number' (e.g. if it's a polyfill).
|
||||
|
||||
|
||||
if (type === exports.Fragment || type === REACT_PROFILER_TYPE || type === REACT_DEBUG_TRACING_MODE_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || type === REACT_LEGACY_HIDDEN_TYPE || enableScopeAPI ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof type === 'object' && type !== null) {
|
||||
if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_BLOCK_TYPE || type[0] === REACT_SERVER_BLOCK_TYPE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
|
||||
function describeComponentFrame (name, source, ownerName) {
|
||||
var sourceInfo = '';
|
||||
|
||||
if (source) {
|
||||
var path = source.fileName;
|
||||
var fileName = path.replace(BEFORE_SLASH_RE, '');
|
||||
|
||||
{
|
||||
// In DEV, include code for a common special case:
|
||||
// prefer "folder/index.js" instead of just "index.js".
|
||||
if (/^index\./.test(fileName)) {
|
||||
var match = path.match(BEFORE_SLASH_RE);
|
||||
|
||||
if (match) {
|
||||
var pathBeforeSlash = match[1];
|
||||
|
||||
if (pathBeforeSlash) {
|
||||
var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
|
||||
fileName = folderName + '/' + fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
|
||||
} else if (ownerName) {
|
||||
sourceInfo = ' (created by ' + ownerName + ')';
|
||||
}
|
||||
|
||||
return '\n in ' + (name || 'Unknown') + sourceInfo;
|
||||
}
|
||||
|
||||
var Resolved = 1;
|
||||
function refineResolvedLazyComponent(lazyComponent) {
|
||||
return lazyComponent._status === Resolved ? lazyComponent._result : null;
|
||||
}
|
||||
|
||||
function getWrappedName(outerType, innerType, wrapperName) {
|
||||
var functionName = innerType.displayName || innerType.name || '';
|
||||
return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
|
||||
}
|
||||
|
||||
function getComponentName(type) {
|
||||
if (type == null) {
|
||||
// Host root, text node or just invalid type.
|
||||
return null;
|
||||
}
|
||||
|
||||
{
|
||||
if (typeof type.tag === 'number') {
|
||||
error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof type === 'function') {
|
||||
return type.displayName || type.name || null;
|
||||
}
|
||||
|
||||
if (typeof type === 'string') {
|
||||
return type;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case exports.Fragment:
|
||||
return 'Fragment';
|
||||
|
||||
case REACT_PORTAL_TYPE:
|
||||
return 'Portal';
|
||||
|
||||
case REACT_PROFILER_TYPE:
|
||||
return "Profiler";
|
||||
|
||||
case REACT_STRICT_MODE_TYPE:
|
||||
return 'StrictMode';
|
||||
|
||||
case REACT_SUSPENSE_TYPE:
|
||||
return 'Suspense';
|
||||
|
||||
case REACT_SUSPENSE_LIST_TYPE:
|
||||
return 'SuspenseList';
|
||||
}
|
||||
|
||||
if (typeof type === 'object') {
|
||||
switch (type.$$typeof) {
|
||||
case REACT_CONTEXT_TYPE:
|
||||
return 'Context.Consumer';
|
||||
|
||||
case REACT_PROVIDER_TYPE:
|
||||
return 'Context.Provider';
|
||||
|
||||
case REACT_FORWARD_REF_TYPE:
|
||||
return getWrappedName(type, type.render, 'ForwardRef');
|
||||
|
||||
case REACT_MEMO_TYPE:
|
||||
return getComponentName(type.type);
|
||||
|
||||
case REACT_BLOCK_TYPE:
|
||||
return getComponentName(type.render);
|
||||
|
||||
case REACT_LAZY_TYPE:
|
||||
{
|
||||
var thenable = type;
|
||||
var resolvedThenable = refineResolvedLazyComponent(thenable);
|
||||
|
||||
if (resolvedThenable) {
|
||||
return getComponentName(resolvedThenable);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
var loggedTypeFailures = {};
|
||||
var currentlyValidatingElement = null;
|
||||
|
||||
function setCurrentlyValidatingElement(element) {
|
||||
currentlyValidatingElement = element;
|
||||
}
|
||||
|
||||
function checkPropTypes(typeSpecs, values, location, componentName, element) {
|
||||
{
|
||||
// $FlowFixMe This is okay but Flow doesn't know it.
|
||||
var has = Function.call.bind(Object.prototype.hasOwnProperty);
|
||||
|
||||
for (var typeSpecName in typeSpecs) {
|
||||
if (has(typeSpecs, typeSpecName)) {
|
||||
var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
|
||||
// fail the render phase where it didn't fail before. So we log it.
|
||||
// After these have been cleaned up, we'll let them throw.
|
||||
|
||||
try {
|
||||
// This is intentionally an invariant that gets caught. It's the same
|
||||
// behavior as without this statement except with a better message.
|
||||
if (typeof typeSpecs[typeSpecName] !== 'function') {
|
||||
var err = Error((componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.');
|
||||
err.name = 'Invariant Violation';
|
||||
throw err;
|
||||
}
|
||||
|
||||
error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
|
||||
} catch (ex) {
|
||||
error$1 = ex;
|
||||
}
|
||||
|
||||
if (error$1 && !(error$1 instanceof Error)) {
|
||||
setCurrentlyValidatingElement(element);
|
||||
|
||||
error('%s: type specification of %s' + ' `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error$1);
|
||||
|
||||
setCurrentlyValidatingElement(null);
|
||||
}
|
||||
|
||||
if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
|
||||
// Only monitor this failure once because there tends to be a lot of the
|
||||
// same error.
|
||||
loggedTypeFailures[error$1.message] = true;
|
||||
setCurrentlyValidatingElement(element);
|
||||
|
||||
error('Failed %s type: %s', location, error$1.message);
|
||||
|
||||
setCurrentlyValidatingElement(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ReactCurrentOwner = require('react/lib/ReactCurrentOwner');
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
var RESERVED_PROPS = {
|
||||
key: true,
|
||||
ref: true,
|
||||
__self: true,
|
||||
__source: true
|
||||
};
|
||||
var specialPropKeyWarningShown;
|
||||
var specialPropRefWarningShown;
|
||||
var didWarnAboutStringRefs;
|
||||
|
||||
{
|
||||
didWarnAboutStringRefs = {};
|
||||
}
|
||||
|
||||
function hasValidRef(config) {
|
||||
{
|
||||
if (hasOwnProperty.call(config, 'ref')) {
|
||||
var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
|
||||
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return config.ref !== undefined;
|
||||
}
|
||||
|
||||
function hasValidKey(config) {
|
||||
{
|
||||
if (hasOwnProperty.call(config, 'key')) {
|
||||
var getter = Object.getOwnPropertyDescriptor(config, 'key').get;
|
||||
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return config.key !== undefined;
|
||||
}
|
||||
|
||||
function defineKeyPropWarningGetter(props, displayName) {
|
||||
{
|
||||
var warnAboutAccessingKey = function () {
|
||||
if (!specialPropKeyWarningShown) {
|
||||
specialPropKeyWarningShown = true;
|
||||
|
||||
error('%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);
|
||||
}
|
||||
};
|
||||
|
||||
warnAboutAccessingKey.isReactWarning = true;
|
||||
Object.defineProperty(props, 'key', {
|
||||
get: warnAboutAccessingKey,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function defineRefPropWarningGetter(props, displayName) {
|
||||
{
|
||||
var warnAboutAccessingRef = function () {
|
||||
if (!specialPropRefWarningShown) {
|
||||
specialPropRefWarningShown = true;
|
||||
|
||||
error('%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);
|
||||
}
|
||||
};
|
||||
|
||||
warnAboutAccessingRef.isReactWarning = true;
|
||||
Object.defineProperty(props, 'ref', {
|
||||
get: warnAboutAccessingRef,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Factory method to create a new React element. This no longer adheres to
|
||||
* the class pattern, so do not use new to call it. Also, instanceof check
|
||||
* will not work. Instead test $$typeof field against Symbol.for('react.element') to check
|
||||
* if something is a React Element.
|
||||
*
|
||||
* @param {*} type
|
||||
* @param {*} props
|
||||
* @param {*} key
|
||||
* @param {string|object} ref
|
||||
* @param {*} owner
|
||||
* @param {*} self A *temporary* helper to detect places where `this` is
|
||||
* different from the `owner` when React.createElement is called, so that we
|
||||
* can warn. We want to get rid of owner and replace string `ref`s with arrow
|
||||
* functions, and as long as `this` and owner are the same, there will be no
|
||||
* change in behavior.
|
||||
* @param {*} source An annotation object (added by a transpiler or otherwise)
|
||||
* indicating filename, line number, and/or other information.
|
||||
* @internal
|
||||
*/
|
||||
|
||||
|
||||
var ReactElement = function (type, key, ref, self, source, owner, props) {
|
||||
var element = {
|
||||
// This tag allows us to uniquely identify this as a React Element
|
||||
$$typeof: REACT_ELEMENT_TYPE,
|
||||
// Built-in properties that belong on the element
|
||||
type: type,
|
||||
key: key,
|
||||
ref: ref,
|
||||
props: props,
|
||||
// Record the component responsible for creating this element.
|
||||
_owner: owner
|
||||
};
|
||||
|
||||
{
|
||||
// The validation flag is currently mutative. We put it on
|
||||
// an external backing store so that we can freeze the whole object.
|
||||
// This can be replaced with a WeakMap once they are implemented in
|
||||
// commonly used development environments.
|
||||
element._store = {}; // To make comparing ReactElements easier for testing purposes, we make
|
||||
// the validation flag non-enumerable (where possible, which should
|
||||
// include every environment we run tests in), so the test framework
|
||||
// ignores it.
|
||||
|
||||
Object.defineProperty(element._store, 'validated', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
value: false
|
||||
}); // self and source are DEV only properties.
|
||||
|
||||
Object.defineProperty(element, '_self', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: self
|
||||
}); // Two elements created in two different places should be considered
|
||||
// equal for testing purposes and therefore we hide it from enumeration.
|
||||
|
||||
Object.defineProperty(element, '_source', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: source
|
||||
});
|
||||
|
||||
if (Object.freeze) {
|
||||
Object.freeze(element.props);
|
||||
Object.freeze(element);
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
};
|
||||
/**
|
||||
* https://github.com/reactjs/rfcs/pull/107
|
||||
* @param {*} type
|
||||
* @param {object} props
|
||||
* @param {string} key
|
||||
*/
|
||||
|
||||
function jsxDEV(type, config, maybeKey, source, self) {
|
||||
{
|
||||
var propName; // Reserved names are extracted
|
||||
|
||||
var props = {};
|
||||
var key = null;
|
||||
var ref = null; // Currently, key can be spread in as a prop. This causes a potential
|
||||
// issue if key is also explicitly declared (ie. <div {...props} key="Hi" />
|
||||
// or <div key="Hi" {...props} /> ). We want to deprecate key spread,
|
||||
// but as an intermediary step, we will use jsxDEV for everything except
|
||||
// <div {...props} key="Hi" />, because we aren't currently able to tell if
|
||||
// key is explicitly declared to be undefined or not.
|
||||
|
||||
if (maybeKey !== undefined) {
|
||||
key = '' + maybeKey;
|
||||
}
|
||||
|
||||
if (hasValidKey(config)) {
|
||||
key = '' + config.key;
|
||||
}
|
||||
|
||||
if (hasValidRef(config)) {
|
||||
ref = config.ref;
|
||||
} // Remaining properties are added to a new props object
|
||||
|
||||
|
||||
for (propName in config) {
|
||||
if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
|
||||
props[propName] = config[propName];
|
||||
}
|
||||
} // Resolve default props
|
||||
|
||||
|
||||
if (type && type.defaultProps) {
|
||||
var defaultProps = type.defaultProps;
|
||||
|
||||
for (propName in defaultProps) {
|
||||
if (props[propName] === undefined) {
|
||||
props[propName] = defaultProps[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (key || ref) {
|
||||
var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type;
|
||||
|
||||
if (key) {
|
||||
defineKeyPropWarningGetter(props, displayName);
|
||||
}
|
||||
|
||||
if (ref) {
|
||||
defineRefPropWarningGetter(props, displayName);
|
||||
}
|
||||
}
|
||||
|
||||
return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
|
||||
}
|
||||
}
|
||||
|
||||
var ReactCurrentOwner$1 = require('react/lib/ReactCurrentOwner');
|
||||
|
||||
function setCurrentlyValidatingElement$1(element) {
|
||||
currentlyValidatingElement = element;
|
||||
}
|
||||
|
||||
var propTypesMisspellWarningShown;
|
||||
|
||||
{
|
||||
propTypesMisspellWarningShown = false;
|
||||
}
|
||||
/**
|
||||
* Verifies the object is a ReactElement.
|
||||
* See https://reactjs.org/docs/react-api.html#isvalidelement
|
||||
* @param {?object} object
|
||||
* @return {boolean} True if `object` is a ReactElement.
|
||||
* @final
|
||||
*/
|
||||
|
||||
function isValidElement(object) {
|
||||
{
|
||||
return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
function getDeclarationErrorAddendum() {
|
||||
{
|
||||
if (ReactCurrentOwner$1.current) {
|
||||
var name = ReactCurrentOwner$1.current.getName();
|
||||
|
||||
if (name) {
|
||||
return '\n\nCheck the render method of `' + name + '`.';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceInfoErrorAddendum(source) {
|
||||
{
|
||||
if (source !== undefined) {
|
||||
var fileName = source.fileName.replace(/^.*[\\\/]/, '');
|
||||
var lineNumber = source.lineNumber;
|
||||
return '\n\nCheck your code at ' + fileName + ':' + lineNumber + '.';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Warn if there's no key explicitly set on dynamic arrays of children or
|
||||
* object keys are not valid. This allows us to keep track of children between
|
||||
* updates.
|
||||
*/
|
||||
|
||||
|
||||
var ownerHasKeyUseWarning = {};
|
||||
|
||||
function getCurrentComponentErrorInfo(parentType) {
|
||||
{
|
||||
var info = getDeclarationErrorAddendum();
|
||||
|
||||
if (!info) {
|
||||
var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;
|
||||
|
||||
if (parentName) {
|
||||
info = "\n\nCheck the top-level render call using <" + parentName + ">.";
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Warn if the element doesn't have an explicit key assigned to it.
|
||||
* This element is in an array. The array could grow and shrink or be
|
||||
* reordered. All children that haven't already been validated are required to
|
||||
* have a "key" property assigned to it. Error statuses are cached so a warning
|
||||
* will only be shown once.
|
||||
*
|
||||
* @internal
|
||||
* @param {ReactElement} element Element that requires a key.
|
||||
* @param {*} parentType element's parent's type.
|
||||
*/
|
||||
|
||||
|
||||
function validateExplicitKey(element, parentType) {
|
||||
{
|
||||
if (!element._store || element._store.validated || element.key != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
element._store.validated = true;
|
||||
var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType);
|
||||
|
||||
if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
|
||||
return;
|
||||
}
|
||||
|
||||
ownerHasKeyUseWarning[currentComponentErrorInfo] = true; // Usually the current owner is the offender, but if it accepts children as a
|
||||
// property, it may be the creator of the child that's responsible for
|
||||
// assigning it a key.
|
||||
|
||||
var childOwner = '';
|
||||
|
||||
if (element && element._owner && element._owner !== ReactCurrentOwner$1.current) {
|
||||
// Give the component that originally created this child.
|
||||
childOwner = " It was passed a child from " + element._owner.getName() + ".";
|
||||
}
|
||||
|
||||
setCurrentlyValidatingElement$1(element);
|
||||
|
||||
error('Each child in a list should have a unique "key" prop.' + '%s%s See https://reactjs.org/link/warning-keys for more information.', currentComponentErrorInfo, childOwner);
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Ensure that every element either is passed in a static location, in an
|
||||
* array with an explicit keys property defined, or in an object literal
|
||||
* with valid key property.
|
||||
*
|
||||
* @internal
|
||||
* @param {ReactNode} node Statically passed child of any type.
|
||||
* @param {*} parentType node's parent's type.
|
||||
*/
|
||||
|
||||
|
||||
function validateChildKeys(node, parentType) {
|
||||
{
|
||||
if (typeof node !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.isArray(node)) {
|
||||
for (var i = 0; i < node.length; i++) {
|
||||
var child = node[i];
|
||||
|
||||
if (isValidElement(child)) {
|
||||
validateExplicitKey(child, parentType);
|
||||
}
|
||||
}
|
||||
} else if (isValidElement(node)) {
|
||||
// This element was passed in a valid location.
|
||||
if (node._store) {
|
||||
node._store.validated = true;
|
||||
}
|
||||
} else if (node) {
|
||||
var iteratorFn = getIteratorFn(node);
|
||||
|
||||
if (typeof iteratorFn === 'function') {
|
||||
// Entry iterators used to provide implicit keys,
|
||||
// but now we print a separate warning for them later.
|
||||
if (iteratorFn !== node.entries) {
|
||||
var iterator = iteratorFn.call(node);
|
||||
var step;
|
||||
|
||||
while (!(step = iterator.next()).done) {
|
||||
if (isValidElement(step.value)) {
|
||||
validateExplicitKey(step.value, parentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Given an element, validate that its props follow the propTypes definition,
|
||||
* provided by the type.
|
||||
*
|
||||
* @param {ReactElement} element
|
||||
*/
|
||||
|
||||
|
||||
function validatePropTypes(element) {
|
||||
{
|
||||
var type = element.type;
|
||||
|
||||
if (type === null || type === undefined || typeof type === 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
var propTypes;
|
||||
|
||||
if (typeof type === 'function') {
|
||||
propTypes = type.propTypes;
|
||||
} else if (typeof type === 'object' && (type.$$typeof === REACT_FORWARD_REF_TYPE || // Note: Memo only checks outer props here.
|
||||
// Inner props are checked in the reconciler.
|
||||
type.$$typeof === REACT_MEMO_TYPE)) {
|
||||
propTypes = type.propTypes;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (propTypes) {
|
||||
// Intentionally inside to avoid triggering lazy initializers:
|
||||
var name = getComponentName(type);
|
||||
checkPropTypes(propTypes, element.props, 'prop', name, element);
|
||||
} else if (type.PropTypes !== undefined && !propTypesMisspellWarningShown) {
|
||||
propTypesMisspellWarningShown = true; // Intentionally inside to avoid triggering lazy initializers:
|
||||
|
||||
var _name = getComponentName(type);
|
||||
|
||||
error('Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?', _name || 'Unknown');
|
||||
}
|
||||
|
||||
if (typeof type.getDefaultProps === 'function' && !type.getDefaultProps.isReactClassApproved) {
|
||||
error('getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.');
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Given a fragment, validate that it can only be provided with fragment props
|
||||
* @param {ReactElement} fragment
|
||||
*/
|
||||
|
||||
|
||||
function validateFragmentProps(fragment) {
|
||||
{
|
||||
var keys = Object.keys(fragment.props);
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
|
||||
if (key !== 'children' && key !== 'key') {
|
||||
setCurrentlyValidatingElement$1(fragment);
|
||||
|
||||
error('Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key);
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fragment.ref !== null) {
|
||||
setCurrentlyValidatingElement$1(fragment);
|
||||
|
||||
error('Invalid attribute `ref` supplied to `React.Fragment`.');
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function jsxWithValidation(type, props, key, isStaticChildren, source, self) {
|
||||
{
|
||||
var validType = isValidElementType(type); // We warn in this case but don't throw. We expect the element creation to
|
||||
// succeed and there will likely be errors in render.
|
||||
|
||||
if (!validType) {
|
||||
var info = '';
|
||||
|
||||
if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
|
||||
info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and named imports.";
|
||||
}
|
||||
|
||||
var sourceInfo = getSourceInfoErrorAddendum(source);
|
||||
|
||||
if (sourceInfo) {
|
||||
info += sourceInfo;
|
||||
} else {
|
||||
info += getDeclarationErrorAddendum();
|
||||
}
|
||||
|
||||
var typeString;
|
||||
|
||||
if (type === null) {
|
||||
typeString = 'null';
|
||||
} else if (Array.isArray(type)) {
|
||||
typeString = 'array';
|
||||
} else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {
|
||||
typeString = "<" + (getComponentName(type.type) || 'Unknown') + " />";
|
||||
info = ' Did you accidentally export a JSX literal instead of a component?';
|
||||
} else {
|
||||
typeString = typeof type;
|
||||
}
|
||||
|
||||
error('React.jsx: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', typeString, info);
|
||||
}
|
||||
|
||||
var element = jsxDEV(type, props, key, source, self); // The result can be nullish if a mock or a custom function is used.
|
||||
// TODO: Drop this when these are no longer allowed as the type argument.
|
||||
|
||||
if (element == null) {
|
||||
return element;
|
||||
} // Skip key warning if the type isn't valid since our key validation logic
|
||||
// doesn't expect a non-string/function type and can throw confusing errors.
|
||||
// We don't want exception behavior to differ between dev and prod.
|
||||
// (Rendering will throw with a helpful message and as soon as the type is
|
||||
// fixed, the key warnings will appear.)
|
||||
|
||||
|
||||
if (validType) {
|
||||
var children = props.children;
|
||||
|
||||
if (children !== undefined) {
|
||||
if (isStaticChildren) {
|
||||
if (Array.isArray(children)) {
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
validateChildKeys(children[i], type);
|
||||
}
|
||||
|
||||
if (Object.freeze) {
|
||||
Object.freeze(children);
|
||||
}
|
||||
} else {
|
||||
error('React.jsx: Static children should always be an array. ' + 'You are likely explicitly calling React.jsxs or React.jsxDEV. ' + 'Use the Babel transform instead.');
|
||||
}
|
||||
} else {
|
||||
validateChildKeys(children, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type === exports.Fragment) {
|
||||
validateFragmentProps(element);
|
||||
} else {
|
||||
validatePropTypes(element);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
} // These two functions exist to still get child warnings in dev
|
||||
|
||||
var jsxDEV$1 = jsxWithValidation ;
|
||||
|
||||
exports.jsxDEV = jsxDEV$1;
|
||||
})();
|
||||
}
|
||||
9
fixtures/legacy-jsx-runtimes/react-15/cjs/react-jsx-dev-runtime.production.min.js
vendored
Normal file
9
fixtures/legacy-jsx-runtimes/react-15/cjs/react-jsx-dev-runtime.production.min.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/** @license React v15.7.0
|
||||
* react-jsx-dev-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
'use strict';require("react");exports.Fragment=60107;if("function"===typeof Symbol&&Symbol.for){var a=Symbol.for;exports.Fragment=a("react.fragment")}exports.jsxDEV=void 0;
|
||||
@@ -0,0 +1,888 @@
|
||||
/** @license React v15.7.0
|
||||
* react-jsx-runtime.development.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
var ReactComponentTreeHook = require('react/lib/ReactComponentTreeHook');
|
||||
|
||||
// ATTENTION
|
||||
// When adding new symbols to this file,
|
||||
// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
|
||||
// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
|
||||
// nor polyfill, then a plain number is used for performance.
|
||||
var REACT_ELEMENT_TYPE = 0xeac7;
|
||||
var REACT_PORTAL_TYPE = 0xeaca;
|
||||
exports.Fragment = 0xeacb;
|
||||
var REACT_STRICT_MODE_TYPE = 0xeacc;
|
||||
var REACT_PROFILER_TYPE = 0xead2;
|
||||
var REACT_PROVIDER_TYPE = 0xeacd;
|
||||
var REACT_CONTEXT_TYPE = 0xeace;
|
||||
var REACT_FORWARD_REF_TYPE = 0xead0;
|
||||
var REACT_SUSPENSE_TYPE = 0xead1;
|
||||
var REACT_SUSPENSE_LIST_TYPE = 0xead8;
|
||||
var REACT_MEMO_TYPE = 0xead3;
|
||||
var REACT_LAZY_TYPE = 0xead4;
|
||||
var REACT_BLOCK_TYPE = 0xead9;
|
||||
var REACT_SERVER_BLOCK_TYPE = 0xeada;
|
||||
var REACT_FUNDAMENTAL_TYPE = 0xead5;
|
||||
var REACT_SCOPE_TYPE = 0xead7;
|
||||
var REACT_OPAQUE_ID_TYPE = 0xeae0;
|
||||
var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1;
|
||||
var REACT_OFFSCREEN_TYPE = 0xeae2;
|
||||
var REACT_LEGACY_HIDDEN_TYPE = 0xeae3;
|
||||
|
||||
if (typeof Symbol === 'function' && Symbol.for) {
|
||||
var symbolFor = Symbol.for;
|
||||
REACT_ELEMENT_TYPE = symbolFor('react.element');
|
||||
REACT_PORTAL_TYPE = symbolFor('react.portal');
|
||||
exports.Fragment = symbolFor('react.fragment');
|
||||
REACT_STRICT_MODE_TYPE = symbolFor('react.strict_mode');
|
||||
REACT_PROFILER_TYPE = symbolFor('react.profiler');
|
||||
REACT_PROVIDER_TYPE = symbolFor('react.provider');
|
||||
REACT_CONTEXT_TYPE = symbolFor('react.context');
|
||||
REACT_FORWARD_REF_TYPE = symbolFor('react.forward_ref');
|
||||
REACT_SUSPENSE_TYPE = symbolFor('react.suspense');
|
||||
REACT_SUSPENSE_LIST_TYPE = symbolFor('react.suspense_list');
|
||||
REACT_MEMO_TYPE = symbolFor('react.memo');
|
||||
REACT_LAZY_TYPE = symbolFor('react.lazy');
|
||||
REACT_BLOCK_TYPE = symbolFor('react.block');
|
||||
REACT_SERVER_BLOCK_TYPE = symbolFor('react.server.block');
|
||||
REACT_FUNDAMENTAL_TYPE = symbolFor('react.fundamental');
|
||||
REACT_SCOPE_TYPE = symbolFor('react.scope');
|
||||
REACT_OPAQUE_ID_TYPE = symbolFor('react.opaque.id');
|
||||
REACT_DEBUG_TRACING_MODE_TYPE = symbolFor('react.debug_trace_mode');
|
||||
REACT_OFFSCREEN_TYPE = symbolFor('react.offscreen');
|
||||
REACT_LEGACY_HIDDEN_TYPE = symbolFor('react.legacy_hidden');
|
||||
}
|
||||
|
||||
var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
|
||||
var FAUX_ITERATOR_SYMBOL = '@@iterator';
|
||||
function getIteratorFn(maybeIterable) {
|
||||
if (maybeIterable === null || typeof maybeIterable !== 'object') {
|
||||
return null;
|
||||
}
|
||||
|
||||
var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
|
||||
|
||||
if (typeof maybeIterator === 'function') {
|
||||
return maybeIterator;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function error(format) {
|
||||
{
|
||||
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
||||
args[_key2 - 1] = arguments[_key2];
|
||||
}
|
||||
|
||||
printWarning('error', format, args);
|
||||
}
|
||||
}
|
||||
|
||||
function printWarning(level, format, args) {
|
||||
// When changing this logic, you might want to also
|
||||
// update consoleWithStackDev.www.js as well.
|
||||
{
|
||||
var stack = '';
|
||||
|
||||
if (currentlyValidatingElement) {
|
||||
stack += ReactComponentTreeHook.getCurrentStackAddendum(currentlyValidatingElement)
|
||||
}
|
||||
|
||||
if (stack !== '') {
|
||||
format += '%s';
|
||||
args = args.concat([stack]);
|
||||
}
|
||||
|
||||
var argsWithFormat = args.map(function (item) {
|
||||
return '' + item;
|
||||
}); // Careful: RN currently depends on this prefix
|
||||
|
||||
argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
|
||||
// breaks IE9: https://github.com/facebook/react/issues/13610
|
||||
// eslint-disable-next-line react-internal/no-production-logging
|
||||
|
||||
Function.prototype.apply.call(console[level], console, argsWithFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// Filter certain DOM attributes (e.g. src, href) if their values are empty strings.
|
||||
|
||||
var enableScopeAPI = false; // Experimental Create Event Handle API.
|
||||
|
||||
function isValidElementType(type) {
|
||||
if (typeof type === 'string' || typeof type === 'function') {
|
||||
return true;
|
||||
} // Note: typeof might be other than 'symbol' or 'number' (e.g. if it's a polyfill).
|
||||
|
||||
|
||||
if (type === exports.Fragment || type === REACT_PROFILER_TYPE || type === REACT_DEBUG_TRACING_MODE_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || type === REACT_LEGACY_HIDDEN_TYPE || enableScopeAPI ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof type === 'object' && type !== null) {
|
||||
if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_BLOCK_TYPE || type[0] === REACT_SERVER_BLOCK_TYPE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
|
||||
function describeComponentFrame (name, source, ownerName) {
|
||||
var sourceInfo = '';
|
||||
|
||||
if (source) {
|
||||
var path = source.fileName;
|
||||
var fileName = path.replace(BEFORE_SLASH_RE, '');
|
||||
|
||||
{
|
||||
// In DEV, include code for a common special case:
|
||||
// prefer "folder/index.js" instead of just "index.js".
|
||||
if (/^index\./.test(fileName)) {
|
||||
var match = path.match(BEFORE_SLASH_RE);
|
||||
|
||||
if (match) {
|
||||
var pathBeforeSlash = match[1];
|
||||
|
||||
if (pathBeforeSlash) {
|
||||
var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
|
||||
fileName = folderName + '/' + fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
|
||||
} else if (ownerName) {
|
||||
sourceInfo = ' (created by ' + ownerName + ')';
|
||||
}
|
||||
|
||||
return '\n in ' + (name || 'Unknown') + sourceInfo;
|
||||
}
|
||||
|
||||
var Resolved = 1;
|
||||
function refineResolvedLazyComponent(lazyComponent) {
|
||||
return lazyComponent._status === Resolved ? lazyComponent._result : null;
|
||||
}
|
||||
|
||||
function getWrappedName(outerType, innerType, wrapperName) {
|
||||
var functionName = innerType.displayName || innerType.name || '';
|
||||
return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
|
||||
}
|
||||
|
||||
function getComponentName(type) {
|
||||
if (type == null) {
|
||||
// Host root, text node or just invalid type.
|
||||
return null;
|
||||
}
|
||||
|
||||
{
|
||||
if (typeof type.tag === 'number') {
|
||||
error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof type === 'function') {
|
||||
return type.displayName || type.name || null;
|
||||
}
|
||||
|
||||
if (typeof type === 'string') {
|
||||
return type;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case exports.Fragment:
|
||||
return 'Fragment';
|
||||
|
||||
case REACT_PORTAL_TYPE:
|
||||
return 'Portal';
|
||||
|
||||
case REACT_PROFILER_TYPE:
|
||||
return "Profiler";
|
||||
|
||||
case REACT_STRICT_MODE_TYPE:
|
||||
return 'StrictMode';
|
||||
|
||||
case REACT_SUSPENSE_TYPE:
|
||||
return 'Suspense';
|
||||
|
||||
case REACT_SUSPENSE_LIST_TYPE:
|
||||
return 'SuspenseList';
|
||||
}
|
||||
|
||||
if (typeof type === 'object') {
|
||||
switch (type.$$typeof) {
|
||||
case REACT_CONTEXT_TYPE:
|
||||
return 'Context.Consumer';
|
||||
|
||||
case REACT_PROVIDER_TYPE:
|
||||
return 'Context.Provider';
|
||||
|
||||
case REACT_FORWARD_REF_TYPE:
|
||||
return getWrappedName(type, type.render, 'ForwardRef');
|
||||
|
||||
case REACT_MEMO_TYPE:
|
||||
return getComponentName(type.type);
|
||||
|
||||
case REACT_BLOCK_TYPE:
|
||||
return getComponentName(type.render);
|
||||
|
||||
case REACT_LAZY_TYPE:
|
||||
{
|
||||
var thenable = type;
|
||||
var resolvedThenable = refineResolvedLazyComponent(thenable);
|
||||
|
||||
if (resolvedThenable) {
|
||||
return getComponentName(resolvedThenable);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
var loggedTypeFailures = {};
|
||||
var currentlyValidatingElement = null;
|
||||
|
||||
function setCurrentlyValidatingElement(element) {
|
||||
{
|
||||
currentlyValidatingElement = element;
|
||||
}
|
||||
}
|
||||
|
||||
function checkPropTypes(typeSpecs, values, location, componentName, element) {
|
||||
{
|
||||
// $FlowFixMe This is okay but Flow doesn't know it.
|
||||
var has = Function.call.bind(Object.prototype.hasOwnProperty);
|
||||
|
||||
for (var typeSpecName in typeSpecs) {
|
||||
if (has(typeSpecs, typeSpecName)) {
|
||||
var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
|
||||
// fail the render phase where it didn't fail before. So we log it.
|
||||
// After these have been cleaned up, we'll let them throw.
|
||||
|
||||
try {
|
||||
// This is intentionally an invariant that gets caught. It's the same
|
||||
// behavior as without this statement except with a better message.
|
||||
if (typeof typeSpecs[typeSpecName] !== 'function') {
|
||||
var err = Error((componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.');
|
||||
err.name = 'Invariant Violation';
|
||||
throw err;
|
||||
}
|
||||
|
||||
error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
|
||||
} catch (ex) {
|
||||
error$1 = ex;
|
||||
}
|
||||
|
||||
if (error$1 && !(error$1 instanceof Error)) {
|
||||
setCurrentlyValidatingElement(element);
|
||||
|
||||
error('%s: type specification of %s' + ' `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error$1);
|
||||
|
||||
setCurrentlyValidatingElement(null);
|
||||
}
|
||||
|
||||
if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
|
||||
// Only monitor this failure once because there tends to be a lot of the
|
||||
// same error.
|
||||
loggedTypeFailures[error$1.message] = true;
|
||||
setCurrentlyValidatingElement(element);
|
||||
|
||||
error('Failed %s type: %s', location, error$1.message);
|
||||
|
||||
setCurrentlyValidatingElement(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ReactCurrentOwner = require('react/lib/ReactCurrentOwner');
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
var RESERVED_PROPS = {
|
||||
key: true,
|
||||
ref: true,
|
||||
__self: true,
|
||||
__source: true
|
||||
};
|
||||
var specialPropKeyWarningShown;
|
||||
var specialPropRefWarningShown;
|
||||
var didWarnAboutStringRefs;
|
||||
|
||||
{
|
||||
didWarnAboutStringRefs = {};
|
||||
}
|
||||
|
||||
function hasValidRef(config) {
|
||||
{
|
||||
if (hasOwnProperty.call(config, 'ref')) {
|
||||
var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
|
||||
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return config.ref !== undefined;
|
||||
}
|
||||
|
||||
function hasValidKey(config) {
|
||||
{
|
||||
if (hasOwnProperty.call(config, 'key')) {
|
||||
var getter = Object.getOwnPropertyDescriptor(config, 'key').get;
|
||||
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return config.key !== undefined;
|
||||
}
|
||||
|
||||
function defineKeyPropWarningGetter(props, displayName) {
|
||||
{
|
||||
var warnAboutAccessingKey = function () {
|
||||
if (!specialPropKeyWarningShown) {
|
||||
specialPropKeyWarningShown = true;
|
||||
|
||||
error('%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);
|
||||
}
|
||||
};
|
||||
|
||||
warnAboutAccessingKey.isReactWarning = true;
|
||||
Object.defineProperty(props, 'key', {
|
||||
get: warnAboutAccessingKey,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function defineRefPropWarningGetter(props, displayName) {
|
||||
{
|
||||
var warnAboutAccessingRef = function () {
|
||||
if (!specialPropRefWarningShown) {
|
||||
specialPropRefWarningShown = true;
|
||||
|
||||
error('%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);
|
||||
}
|
||||
};
|
||||
|
||||
warnAboutAccessingRef.isReactWarning = true;
|
||||
Object.defineProperty(props, 'ref', {
|
||||
get: warnAboutAccessingRef,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Factory method to create a new React element. This no longer adheres to
|
||||
* the class pattern, so do not use new to call it. Also, instanceof check
|
||||
* will not work. Instead test $$typeof field against Symbol.for('react.element') to check
|
||||
* if something is a React Element.
|
||||
*
|
||||
* @param {*} type
|
||||
* @param {*} props
|
||||
* @param {*} key
|
||||
* @param {string|object} ref
|
||||
* @param {*} owner
|
||||
* @param {*} self A *temporary* helper to detect places where `this` is
|
||||
* different from the `owner` when React.createElement is called, so that we
|
||||
* can warn. We want to get rid of owner and replace string `ref`s with arrow
|
||||
* functions, and as long as `this` and owner are the same, there will be no
|
||||
* change in behavior.
|
||||
* @param {*} source An annotation object (added by a transpiler or otherwise)
|
||||
* indicating filename, line number, and/or other information.
|
||||
* @internal
|
||||
*/
|
||||
|
||||
|
||||
var ReactElement = function (type, key, ref, self, source, owner, props) {
|
||||
var element = {
|
||||
// This tag allows us to uniquely identify this as a React Element
|
||||
$$typeof: REACT_ELEMENT_TYPE,
|
||||
// Built-in properties that belong on the element
|
||||
type: type,
|
||||
key: key,
|
||||
ref: ref,
|
||||
props: props,
|
||||
// Record the component responsible for creating this element.
|
||||
_owner: owner
|
||||
};
|
||||
|
||||
{
|
||||
// The validation flag is currently mutative. We put it on
|
||||
// an external backing store so that we can freeze the whole object.
|
||||
// This can be replaced with a WeakMap once they are implemented in
|
||||
// commonly used development environments.
|
||||
element._store = {}; // To make comparing ReactElements easier for testing purposes, we make
|
||||
// the validation flag non-enumerable (where possible, which should
|
||||
// include every environment we run tests in), so the test framework
|
||||
// ignores it.
|
||||
|
||||
Object.defineProperty(element._store, 'validated', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
value: false
|
||||
}); // self and source are DEV only properties.
|
||||
|
||||
Object.defineProperty(element, '_self', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: self
|
||||
}); // Two elements created in two different places should be considered
|
||||
// equal for testing purposes and therefore we hide it from enumeration.
|
||||
|
||||
Object.defineProperty(element, '_source', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: source
|
||||
});
|
||||
|
||||
if (Object.freeze) {
|
||||
Object.freeze(element.props);
|
||||
Object.freeze(element);
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
};
|
||||
/**
|
||||
* https://github.com/reactjs/rfcs/pull/107
|
||||
* @param {*} type
|
||||
* @param {object} props
|
||||
* @param {string} key
|
||||
*/
|
||||
|
||||
function jsxDEV(type, config, maybeKey, source, self) {
|
||||
{
|
||||
var propName; // Reserved names are extracted
|
||||
|
||||
var props = {};
|
||||
var key = null;
|
||||
var ref = null; // Currently, key can be spread in as a prop. This causes a potential
|
||||
// issue if key is also explicitly declared (ie. <div {...props} key="Hi" />
|
||||
// or <div key="Hi" {...props} /> ). We want to deprecate key spread,
|
||||
// but as an intermediary step, we will use jsxDEV for everything except
|
||||
// <div {...props} key="Hi" />, because we aren't currently able to tell if
|
||||
// key is explicitly declared to be undefined or not.
|
||||
|
||||
if (maybeKey !== undefined) {
|
||||
key = '' + maybeKey;
|
||||
}
|
||||
|
||||
if (hasValidKey(config)) {
|
||||
key = '' + config.key;
|
||||
}
|
||||
|
||||
if (hasValidRef(config)) {
|
||||
ref = config.ref;
|
||||
} // Remaining properties are added to a new props object
|
||||
|
||||
|
||||
for (propName in config) {
|
||||
if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
|
||||
props[propName] = config[propName];
|
||||
}
|
||||
} // Resolve default props
|
||||
|
||||
|
||||
if (type && type.defaultProps) {
|
||||
var defaultProps = type.defaultProps;
|
||||
|
||||
for (propName in defaultProps) {
|
||||
if (props[propName] === undefined) {
|
||||
props[propName] = defaultProps[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (key || ref) {
|
||||
var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type;
|
||||
|
||||
if (key) {
|
||||
defineKeyPropWarningGetter(props, displayName);
|
||||
}
|
||||
|
||||
if (ref) {
|
||||
defineRefPropWarningGetter(props, displayName);
|
||||
}
|
||||
}
|
||||
|
||||
return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
|
||||
}
|
||||
}
|
||||
|
||||
var ReactCurrentOwner$1 = require('react/lib/ReactCurrentOwner');
|
||||
|
||||
function setCurrentlyValidatingElement$1(element) {
|
||||
currentlyValidatingElement = element;
|
||||
}
|
||||
|
||||
var propTypesMisspellWarningShown;
|
||||
|
||||
{
|
||||
propTypesMisspellWarningShown = false;
|
||||
}
|
||||
/**
|
||||
* Verifies the object is a ReactElement.
|
||||
* See https://reactjs.org/docs/react-api.html#isvalidelement
|
||||
* @param {?object} object
|
||||
* @return {boolean} True if `object` is a ReactElement.
|
||||
* @final
|
||||
*/
|
||||
|
||||
function isValidElement(object) {
|
||||
{
|
||||
return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
function getDeclarationErrorAddendum() {
|
||||
{
|
||||
if (ReactCurrentOwner$1.current) {
|
||||
var name = ReactCurrentOwner$1.current.getName();
|
||||
|
||||
if (name) {
|
||||
return '\n\nCheck the render method of `' + name + '`.';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceInfoErrorAddendum(source) {
|
||||
{
|
||||
if (source !== undefined) {
|
||||
var fileName = source.fileName.replace(/^.*[\\\/]/, '');
|
||||
var lineNumber = source.lineNumber;
|
||||
return '\n\nCheck your code at ' + fileName + ':' + lineNumber + '.';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Warn if there's no key explicitly set on dynamic arrays of children or
|
||||
* object keys are not valid. This allows us to keep track of children between
|
||||
* updates.
|
||||
*/
|
||||
|
||||
|
||||
var ownerHasKeyUseWarning = {};
|
||||
|
||||
function getCurrentComponentErrorInfo(parentType) {
|
||||
{
|
||||
var info = getDeclarationErrorAddendum();
|
||||
|
||||
if (!info) {
|
||||
var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;
|
||||
|
||||
if (parentName) {
|
||||
info = "\n\nCheck the top-level render call using <" + parentName + ">.";
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Warn if the element doesn't have an explicit key assigned to it.
|
||||
* This element is in an array. The array could grow and shrink or be
|
||||
* reordered. All children that haven't already been validated are required to
|
||||
* have a "key" property assigned to it. Error statuses are cached so a warning
|
||||
* will only be shown once.
|
||||
*
|
||||
* @internal
|
||||
* @param {ReactElement} element Element that requires a key.
|
||||
* @param {*} parentType element's parent's type.
|
||||
*/
|
||||
|
||||
|
||||
function validateExplicitKey(element, parentType) {
|
||||
{
|
||||
if (!element._store || element._store.validated || element.key != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
element._store.validated = true;
|
||||
var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType);
|
||||
|
||||
if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
|
||||
return;
|
||||
}
|
||||
|
||||
ownerHasKeyUseWarning[currentComponentErrorInfo] = true; // Usually the current owner is the offender, but if it accepts children as a
|
||||
// property, it may be the creator of the child that's responsible for
|
||||
// assigning it a key.
|
||||
|
||||
var childOwner = '';
|
||||
|
||||
if (element && element._owner && element._owner !== ReactCurrentOwner$1.current) {
|
||||
// Give the component that originally created this child.
|
||||
childOwner = " It was passed a child from " + element._owner.getName() + ".";
|
||||
}
|
||||
|
||||
setCurrentlyValidatingElement$1(element);
|
||||
|
||||
error('Each child in a list should have a unique "key" prop.' + '%s%s See https://reactjs.org/link/warning-keys for more information.', currentComponentErrorInfo, childOwner);
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Ensure that every element either is passed in a static location, in an
|
||||
* array with an explicit keys property defined, or in an object literal
|
||||
* with valid key property.
|
||||
*
|
||||
* @internal
|
||||
* @param {ReactNode} node Statically passed child of any type.
|
||||
* @param {*} parentType node's parent's type.
|
||||
*/
|
||||
|
||||
|
||||
function validateChildKeys(node, parentType) {
|
||||
{
|
||||
if (typeof node !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.isArray(node)) {
|
||||
for (var i = 0; i < node.length; i++) {
|
||||
var child = node[i];
|
||||
|
||||
if (isValidElement(child)) {
|
||||
validateExplicitKey(child, parentType);
|
||||
}
|
||||
}
|
||||
} else if (isValidElement(node)) {
|
||||
// This element was passed in a valid location.
|
||||
if (node._store) {
|
||||
node._store.validated = true;
|
||||
}
|
||||
} else if (node) {
|
||||
var iteratorFn = getIteratorFn(node);
|
||||
|
||||
if (typeof iteratorFn === 'function') {
|
||||
// Entry iterators used to provide implicit keys,
|
||||
// but now we print a separate warning for them later.
|
||||
if (iteratorFn !== node.entries) {
|
||||
var iterator = iteratorFn.call(node);
|
||||
var step;
|
||||
|
||||
while (!(step = iterator.next()).done) {
|
||||
if (isValidElement(step.value)) {
|
||||
validateExplicitKey(step.value, parentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Given an element, validate that its props follow the propTypes definition,
|
||||
* provided by the type.
|
||||
*
|
||||
* @param {ReactElement} element
|
||||
*/
|
||||
|
||||
|
||||
function validatePropTypes(element) {
|
||||
{
|
||||
var type = element.type;
|
||||
|
||||
if (type === null || type === undefined || typeof type === 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
var propTypes;
|
||||
|
||||
if (typeof type === 'function') {
|
||||
propTypes = type.propTypes;
|
||||
} else if (typeof type === 'object' && (type.$$typeof === REACT_FORWARD_REF_TYPE || // Note: Memo only checks outer props here.
|
||||
// Inner props are checked in the reconciler.
|
||||
type.$$typeof === REACT_MEMO_TYPE)) {
|
||||
propTypes = type.propTypes;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (propTypes) {
|
||||
// Intentionally inside to avoid triggering lazy initializers:
|
||||
var name = getComponentName(type);
|
||||
checkPropTypes(propTypes, element.props, 'prop', name, element);
|
||||
} else if (type.PropTypes !== undefined && !propTypesMisspellWarningShown) {
|
||||
propTypesMisspellWarningShown = true; // Intentionally inside to avoid triggering lazy initializers:
|
||||
|
||||
var _name = getComponentName(type);
|
||||
|
||||
error('Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?', _name || 'Unknown');
|
||||
}
|
||||
|
||||
if (typeof type.getDefaultProps === 'function' && !type.getDefaultProps.isReactClassApproved) {
|
||||
error('getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.');
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Given a fragment, validate that it can only be provided with fragment props
|
||||
* @param {ReactElement} fragment
|
||||
*/
|
||||
|
||||
|
||||
function validateFragmentProps(fragment) {
|
||||
{
|
||||
var keys = Object.keys(fragment.props);
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
|
||||
if (key !== 'children' && key !== 'key') {
|
||||
setCurrentlyValidatingElement$1(fragment);
|
||||
|
||||
error('Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key);
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fragment.ref !== null) {
|
||||
setCurrentlyValidatingElement$1(fragment);
|
||||
|
||||
error('Invalid attribute `ref` supplied to `React.Fragment`.');
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function jsxWithValidation(type, props, key, isStaticChildren, source, self) {
|
||||
{
|
||||
var validType = isValidElementType(type); // We warn in this case but don't throw. We expect the element creation to
|
||||
// succeed and there will likely be errors in render.
|
||||
|
||||
if (!validType) {
|
||||
var info = '';
|
||||
|
||||
if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
|
||||
info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and named imports.";
|
||||
}
|
||||
|
||||
var sourceInfo = getSourceInfoErrorAddendum(source);
|
||||
|
||||
if (sourceInfo) {
|
||||
info += sourceInfo;
|
||||
} else {
|
||||
info += getDeclarationErrorAddendum();
|
||||
}
|
||||
|
||||
var typeString;
|
||||
|
||||
if (type === null) {
|
||||
typeString = 'null';
|
||||
} else if (Array.isArray(type)) {
|
||||
typeString = 'array';
|
||||
} else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {
|
||||
typeString = "<" + (getComponentName(type.type) || 'Unknown') + " />";
|
||||
info = ' Did you accidentally export a JSX literal instead of a component?';
|
||||
} else {
|
||||
typeString = typeof type;
|
||||
}
|
||||
|
||||
error('React.jsx: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', typeString, info);
|
||||
}
|
||||
|
||||
var element = jsxDEV(type, props, key, source, self); // The result can be nullish if a mock or a custom function is used.
|
||||
// TODO: Drop this when these are no longer allowed as the type argument.
|
||||
|
||||
if (element == null) {
|
||||
return element;
|
||||
} // Skip key warning if the type isn't valid since our key validation logic
|
||||
// doesn't expect a non-string/function type and can throw confusing errors.
|
||||
// We don't want exception behavior to differ between dev and prod.
|
||||
// (Rendering will throw with a helpful message and as soon as the type is
|
||||
// fixed, the key warnings will appear.)
|
||||
|
||||
|
||||
if (validType) {
|
||||
var children = props.children;
|
||||
|
||||
if (children !== undefined) {
|
||||
if (isStaticChildren) {
|
||||
if (Array.isArray(children)) {
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
validateChildKeys(children[i], type);
|
||||
}
|
||||
|
||||
if (Object.freeze) {
|
||||
Object.freeze(children);
|
||||
}
|
||||
} else {
|
||||
error('React.jsx: Static children should always be an array. ' + 'You are likely explicitly calling React.jsxs or React.jsxDEV. ' + 'Use the Babel transform instead.');
|
||||
}
|
||||
} else {
|
||||
validateChildKeys(children, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type === exports.Fragment) {
|
||||
validateFragmentProps(element);
|
||||
} else {
|
||||
validatePropTypes(element);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
} // These two functions exist to still get child warnings in dev
|
||||
// even with the prod transform. This means that jsxDEV is purely
|
||||
// opt-in behavior for better messages but that we won't stop
|
||||
// giving you warnings if you use production apis.
|
||||
|
||||
function jsxWithValidationStatic(type, props, key) {
|
||||
{
|
||||
return jsxWithValidation(type, props, key, true);
|
||||
}
|
||||
}
|
||||
function jsxWithValidationDynamic(type, props, key) {
|
||||
{
|
||||
return jsxWithValidation(type, props, key, false);
|
||||
}
|
||||
}
|
||||
|
||||
var jsx = jsxWithValidationDynamic ; // we may want to special case jsxs internally to take advantage of static children.
|
||||
// for now we can ship identical prod functions
|
||||
|
||||
var jsxs = jsxWithValidationStatic ;
|
||||
|
||||
exports.jsx = jsx;
|
||||
exports.jsxs = jsxs;
|
||||
})();
|
||||
}
|
||||
10
fixtures/legacy-jsx-runtimes/react-15/cjs/react-jsx-runtime.production.min.js
vendored
Normal file
10
fixtures/legacy-jsx-runtimes/react-15/cjs/react-jsx-runtime.production.min.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/** @license React v15.7.0
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
'use strict';var f=require("react"),g=60103;exports.Fragment=60107;if("function"===typeof Symbol&&Symbol.for){var h=Symbol.for;g=h("react.element");exports.Fragment=h("react.fragment")}var m=require("react/lib/ReactCurrentOwner"),n=Object.prototype.hasOwnProperty,p={key:!0,ref:!0,__self:!0,__source:!0};
|
||||
function q(c,a,k){var b,d={},e=null,l=null;void 0!==k&&(e=""+k);void 0!==a.key&&(e=""+a.key);void 0!==a.ref&&(l=a.ref);for(b in a)n.call(a,b)&&!p.hasOwnProperty(b)&&(d[b]=a[b]);if(c&&c.defaultProps)for(b in a=c.defaultProps,a)void 0===d[b]&&(d[b]=a[b]);return{$$typeof:g,type:c,key:e,ref:l,props:d,_owner:m.current}}exports.jsx=q;exports.jsxs=q;
|
||||
7
fixtures/legacy-jsx-runtimes/react-15/jsx-dev-runtime.js
vendored
Normal file
7
fixtures/legacy-jsx-runtimes/react-15/jsx-dev-runtime.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-jsx-dev-runtime.production.min.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-jsx-dev-runtime.development.js');
|
||||
}
|
||||
7
fixtures/legacy-jsx-runtimes/react-15/jsx-runtime.js
vendored
Normal file
7
fixtures/legacy-jsx-runtimes/react-15/jsx-runtime.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-jsx-runtime.production.min.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-jsx-runtime.development.js');
|
||||
}
|
||||
6
fixtures/legacy-jsx-runtimes/react-15/package.json
Normal file
6
fixtures/legacy-jsx-runtimes/react-15/package.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "15",
|
||||
"react-dom": "15"
|
||||
}
|
||||
}
|
||||
775
fixtures/legacy-jsx-runtimes/react-15/react-15.test.js
Normal file
775
fixtures/legacy-jsx-runtimes/react-15/react-15.test.js
Normal file
@@ -0,0 +1,775 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails react-core
|
||||
*/
|
||||
|
||||
// These tests are based on ReactJSXElement-test,
|
||||
// ReactJSXElementValidator-test, ReactComponent-test,
|
||||
// and ReactElementJSX-test.
|
||||
|
||||
jest.mock('react/jsx-runtime', () => require('./jsx-runtime'), {virtual: true});
|
||||
jest.mock('react/jsx-dev-runtime', () => require('./jsx-dev-runtime'), {
|
||||
virtual: true,
|
||||
});
|
||||
|
||||
let React = require('react');
|
||||
let ReactDOM = require('react-dom');
|
||||
let ReactTestUtils = {
|
||||
renderIntoDocument(el) {
|
||||
const container = document.createElement('div');
|
||||
return ReactDOM.render(el, container);
|
||||
},
|
||||
};
|
||||
let PropTypes = require('prop-types');
|
||||
let Component = class Component extends React.Component {
|
||||
render() {
|
||||
return <div />;
|
||||
}
|
||||
};
|
||||
let RequiredPropComponent = class extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
};
|
||||
RequiredPropComponent.displayName = 'RequiredPropComponent';
|
||||
RequiredPropComponent.propTypes = {prop: PropTypes.string.isRequired};
|
||||
|
||||
it('works', () => {
|
||||
const container = document.createElement('div');
|
||||
ReactDOM.render(<h1>hello</h1>, container);
|
||||
expect(container.textContent).toBe('hello');
|
||||
});
|
||||
|
||||
it('returns a complete element according to spec', () => {
|
||||
const element = <Component />;
|
||||
expect(element.type).toBe(Component);
|
||||
expect(element.key).toBe(null);
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('allows a lower-case to be passed as the string type', () => {
|
||||
const element = <div />;
|
||||
expect(element.type).toBe('div');
|
||||
expect(element.key).toBe(null);
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('allows a string to be passed as the type', () => {
|
||||
const TagName = 'div';
|
||||
const element = <TagName />;
|
||||
expect(element.type).toBe('div');
|
||||
expect(element.key).toBe(null);
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('returns an immutable element', () => {
|
||||
const element = <Component />;
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
expect(() => (element.type = 'div')).toThrow();
|
||||
} else {
|
||||
expect(() => (element.type = 'div')).not.toThrow();
|
||||
}
|
||||
});
|
||||
|
||||
it('does not reuse the object that is spread into props', () => {
|
||||
const config = {foo: 1};
|
||||
const element = <Component {...config} />;
|
||||
expect(element.props.foo).toBe(1);
|
||||
config.foo = 2;
|
||||
expect(element.props.foo).toBe(1);
|
||||
});
|
||||
|
||||
it('extracts key and ref from the rest of the props', () => {
|
||||
const element = <Component key="12" ref="34" foo="56" />;
|
||||
expect(element.type).toBe(Component);
|
||||
expect(element.key).toBe('12');
|
||||
expect(element.ref).toBe('34');
|
||||
const expectation = {foo: '56'};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('coerces the key to a string', () => {
|
||||
const element = <Component key={12} foo="56" />;
|
||||
expect(element.type).toBe(Component);
|
||||
expect(element.key).toBe('12');
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {foo: '56'};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('merges JSX children onto the children prop', () => {
|
||||
const a = 1;
|
||||
const element = <Component children="text">{a}</Component>;
|
||||
expect(element.props.children).toBe(a);
|
||||
});
|
||||
|
||||
it('does not override children if no JSX children are provided', () => {
|
||||
const element = <Component children="text" />;
|
||||
expect(element.props.children).toBe('text');
|
||||
});
|
||||
|
||||
it('overrides children if null is provided as a JSX child', () => {
|
||||
const element = <Component children="text">{null}</Component>;
|
||||
expect(element.props.children).toBe(null);
|
||||
});
|
||||
|
||||
it('overrides children if undefined is provided as an argument', () => {
|
||||
const element = <Component children="text">{undefined}</Component>;
|
||||
expect(element.props.children).toBe(undefined);
|
||||
|
||||
const element2 = React.cloneElement(
|
||||
<Component children="text" />,
|
||||
{},
|
||||
undefined
|
||||
);
|
||||
expect(element2.props.children).toBe(undefined);
|
||||
});
|
||||
|
||||
it('merges JSX children onto the children prop in an array', () => {
|
||||
const a = 1;
|
||||
const b = 2;
|
||||
const c = 3;
|
||||
const element = (
|
||||
<Component>
|
||||
{a}
|
||||
{b}
|
||||
{c}
|
||||
</Component>
|
||||
);
|
||||
expect(element.props.children).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it('allows static methods to be called using the type property', () => {
|
||||
class StaticMethodComponent {
|
||||
static someStaticMethod() {
|
||||
return 'someReturnValue';
|
||||
}
|
||||
render() {
|
||||
return <div />;
|
||||
}
|
||||
}
|
||||
|
||||
const element = <StaticMethodComponent />;
|
||||
expect(element.type.someStaticMethod()).toBe('someReturnValue');
|
||||
});
|
||||
|
||||
it('identifies valid elements', () => {
|
||||
expect(React.isValidElement(<div />)).toEqual(true);
|
||||
expect(React.isValidElement(<Component />)).toEqual(true);
|
||||
|
||||
expect(React.isValidElement(null)).toEqual(false);
|
||||
expect(React.isValidElement(true)).toEqual(false);
|
||||
expect(React.isValidElement({})).toEqual(false);
|
||||
expect(React.isValidElement('string')).toEqual(false);
|
||||
expect(React.isValidElement(Component)).toEqual(false);
|
||||
expect(React.isValidElement({type: 'div', props: {}})).toEqual(false);
|
||||
});
|
||||
|
||||
it('is indistinguishable from a plain object', () => {
|
||||
const element = <div className="foo" />;
|
||||
const object = {};
|
||||
expect(element.constructor).toBe(object.constructor);
|
||||
});
|
||||
|
||||
it('should use default prop value when removing a prop', () => {
|
||||
Component.defaultProps = {fruit: 'persimmon'};
|
||||
|
||||
const container = document.createElement('div');
|
||||
const instance = ReactDOM.render(<Component fruit="mango" />, container);
|
||||
expect(instance.props.fruit).toBe('mango');
|
||||
|
||||
ReactDOM.render(<Component />, container);
|
||||
expect(instance.props.fruit).toBe('persimmon');
|
||||
});
|
||||
|
||||
it('should normalize props with default values', () => {
|
||||
class NormalizingComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
NormalizingComponent.defaultProps = {prop: 'testKey'};
|
||||
|
||||
const container = document.createElement('div');
|
||||
const instance = ReactDOM.render(<NormalizingComponent />, container);
|
||||
expect(instance.props.prop).toBe('testKey');
|
||||
|
||||
const inst2 = ReactDOM.render(
|
||||
<NormalizingComponent prop={null} />,
|
||||
container
|
||||
);
|
||||
expect(inst2.props.prop).toBe(null);
|
||||
});
|
||||
|
||||
it('warns for keys for arrays of elements in children position', () => {
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<Component>{[<Component />, <Component />]}</Component>
|
||||
)
|
||||
).toErrorDev('Each child in a list should have a unique "key" prop.');
|
||||
});
|
||||
|
||||
it('warns for keys for arrays of elements with owner info', () => {
|
||||
class InnerComponent extends React.Component {
|
||||
render() {
|
||||
return <Component>{this.props.childSet}</Component>;
|
||||
}
|
||||
}
|
||||
|
||||
class ComponentWrapper extends React.Component {
|
||||
render() {
|
||||
return <InnerComponent childSet={[<Component />, <Component />]} />;
|
||||
}
|
||||
}
|
||||
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<ComponentWrapper />)
|
||||
).toErrorDev(
|
||||
'Each child in a list should have a unique "key" prop.' +
|
||||
'\n\nCheck the render method of `InnerComponent`. ' +
|
||||
'It was passed a child from ComponentWrapper. '
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warn for arrays of elements with keys', () => {
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<Component>{[<Component key="#1" />, <Component key="#2" />]}</Component>
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warn for iterable elements with keys', () => {
|
||||
const iterable = {
|
||||
'@@iterator': function() {
|
||||
let i = 0;
|
||||
return {
|
||||
next: function() {
|
||||
const done = ++i > 2;
|
||||
return {
|
||||
value: done ? undefined : <Component key={'#' + i} />,
|
||||
done: done,
|
||||
};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component>{iterable}</Component>);
|
||||
});
|
||||
|
||||
it('does not warn for numeric keys in entry iterable as a child', () => {
|
||||
const iterable = {
|
||||
'@@iterator': function() {
|
||||
let i = 0;
|
||||
return {
|
||||
next: function() {
|
||||
const done = ++i > 2;
|
||||
return {value: done ? undefined : [i, <Component />], done: done};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
iterable.entries = iterable['@@iterator'];
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component>{iterable}</Component>);
|
||||
});
|
||||
|
||||
it('does not warn when the element is directly as children', () => {
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<Component>
|
||||
<Component />
|
||||
<Component />
|
||||
</Component>
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warn when the child array contains non-elements', () => {
|
||||
void (<Component>{[{}, {}]}</Component>);
|
||||
});
|
||||
|
||||
it('should give context for PropType errors in nested components.', () => {
|
||||
// In this test, we're making sure that if a proptype error is found in a
|
||||
// component, we give a small hint as to which parent instantiated that
|
||||
// component as per warnings about key usage in ReactElementValidator.
|
||||
function MyComp({color}) {
|
||||
return <div>My color is {color}</div>;
|
||||
}
|
||||
MyComp.propTypes = {
|
||||
color: PropTypes.string,
|
||||
};
|
||||
class ParentComp extends React.Component {
|
||||
render() {
|
||||
return <MyComp color={123} />;
|
||||
}
|
||||
}
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<ParentComp />)).toErrorDev(
|
||||
'Warning: Failed prop type: ' +
|
||||
'Invalid prop `color` of type `number` supplied to `MyComp`, ' +
|
||||
'expected `string`.\n' +
|
||||
' in MyComp (at **)\n' +
|
||||
' in ParentComp (at **)'
|
||||
);
|
||||
});
|
||||
|
||||
it('gives a helpful error when passing null, undefined, or boolean', () => {
|
||||
const Undefined = undefined;
|
||||
const Null = null;
|
||||
const True = true;
|
||||
const Div = 'div';
|
||||
expect(
|
||||
() => void (<Undefined />)
|
||||
).toErrorDev(
|
||||
'Warning: React.jsx: type is invalid -- expected a string ' +
|
||||
'(for built-in components) or a class/function (for composite ' +
|
||||
'components) but got: undefined. You likely forgot to export your ' +
|
||||
"component from the file it's defined in, or you might have mixed up " +
|
||||
'default and named imports.' +
|
||||
(process.env.BABEL_ENV === 'development'
|
||||
? '\n\nCheck your code at **.'
|
||||
: ''),
|
||||
{withoutStack: true}
|
||||
);
|
||||
expect(
|
||||
() => void (<Null />)
|
||||
).toErrorDev(
|
||||
'Warning: React.jsx: type is invalid -- expected a string ' +
|
||||
'(for built-in components) or a class/function (for composite ' +
|
||||
'components) but got: null.' +
|
||||
(process.env.BABEL_ENV === 'development'
|
||||
? '\n\nCheck your code at **.'
|
||||
: ''),
|
||||
{withoutStack: true}
|
||||
);
|
||||
expect(
|
||||
() => void (<True />)
|
||||
).toErrorDev(
|
||||
'Warning: React.jsx: type is invalid -- expected a string ' +
|
||||
'(for built-in components) or a class/function (for composite ' +
|
||||
'components) but got: boolean.' +
|
||||
(process.env.BABEL_ENV === 'development'
|
||||
? '\n\nCheck your code at **.'
|
||||
: ''),
|
||||
{withoutStack: true}
|
||||
);
|
||||
// No error expected
|
||||
void (<Div />);
|
||||
});
|
||||
|
||||
it('should check default prop values', () => {
|
||||
RequiredPropComponent.defaultProps = {prop: null};
|
||||
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<RequiredPropComponent />)
|
||||
).toErrorDev(
|
||||
'Warning: Failed prop type: The prop `prop` is marked as required in ' +
|
||||
'`RequiredPropComponent`, but its value is `null`.\n' +
|
||||
' in RequiredPropComponent (at **)'
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn on invalid prop types', () => {
|
||||
// Since there is no prevalidation step for ES6 classes, there is no hook
|
||||
// for us to issue a warning earlier than element creation when the error
|
||||
// actually occurs. Since this step is skipped in production, we should just
|
||||
// warn instead of throwing for this case.
|
||||
class NullPropTypeComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
NullPropTypeComponent.propTypes = {
|
||||
prop: null,
|
||||
};
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<NullPropTypeComponent />)
|
||||
).toErrorDev(
|
||||
'NullPropTypeComponent: prop type `prop` is invalid; it must be a ' +
|
||||
'function, usually from the `prop-types` package,'
|
||||
);
|
||||
});
|
||||
|
||||
xit('should warn on invalid context types', () => {
|
||||
class NullContextTypeComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
NullContextTypeComponent.contextTypes = {
|
||||
prop: null,
|
||||
};
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<NullContextTypeComponent />)
|
||||
).toErrorDev(
|
||||
'NullContextTypeComponent: type `prop` is invalid; it must ' +
|
||||
'be a function, usually from the `prop-types` package,'
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn if getDefaultProps is specified on the class', () => {
|
||||
class GetDefaultPropsComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
GetDefaultPropsComponent.getDefaultProps = () => ({
|
||||
prop: 'foo',
|
||||
});
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<GetDefaultPropsComponent />)
|
||||
).toErrorDev(
|
||||
'getDefaultProps is only used on classic React.createClass definitions.' +
|
||||
' Use a static property named `defaultProps` instead.',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn if component declares PropTypes instead of propTypes', () => {
|
||||
class MisspelledPropTypesComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
MisspelledPropTypesComponent.PropTypes = {
|
||||
prop: PropTypes.string,
|
||||
};
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<MisspelledPropTypesComponent prop="hi" />
|
||||
)
|
||||
).toErrorDev(
|
||||
'Warning: Component MisspelledPropTypesComponent declared `PropTypes` ' +
|
||||
'instead of `propTypes`. Did you misspell the property assignment?',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
// Not supported.
|
||||
xit('warns for fragments with illegal attributes', () => {
|
||||
class Foo extends React.Component {
|
||||
render() {
|
||||
return <React.Fragment a={1}>hello</React.Fragment>;
|
||||
}
|
||||
}
|
||||
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<Foo />)).toErrorDev(
|
||||
'Invalid prop `a` supplied to `React.Fragment`. React.Fragment ' +
|
||||
'can only have `key` and `children` props.'
|
||||
);
|
||||
});
|
||||
|
||||
// Not supported.
|
||||
xit('warns for fragments with refs', () => {
|
||||
class Foo extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<React.Fragment
|
||||
ref={bar => {
|
||||
this.foo = bar;
|
||||
}}>
|
||||
hello
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<Foo />)).toErrorDev(
|
||||
'Invalid attribute `ref` supplied to `React.Fragment`.'
|
||||
);
|
||||
});
|
||||
|
||||
// Not supported.
|
||||
xit('does not warn for fragments of multiple elements without keys', () => {
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<>
|
||||
<span>1</span>
|
||||
<span>2</span>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
// Not supported.
|
||||
xit('warns for fragments of multiple elements with same key', () => {
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<>
|
||||
<span key="a">1</span>
|
||||
<span key="a">2</span>
|
||||
<span key="b">3</span>
|
||||
</>
|
||||
)
|
||||
).toErrorDev('Encountered two children with the same key, `a`.', {
|
||||
withoutStack: true,
|
||||
});
|
||||
});
|
||||
|
||||
// Not supported.
|
||||
xit('does not call lazy initializers eagerly', () => {
|
||||
let didCall = false;
|
||||
const Lazy = React.lazy(() => {
|
||||
didCall = true;
|
||||
return {then() {}};
|
||||
});
|
||||
<Lazy />;
|
||||
expect(didCall).toBe(false);
|
||||
});
|
||||
|
||||
it('supports classic refs', () => {
|
||||
class Foo extends React.Component {
|
||||
render() {
|
||||
return <div className="foo" ref="inner" />;
|
||||
}
|
||||
}
|
||||
const container = document.createElement('div');
|
||||
const instance = ReactDOM.render(<Foo />, container);
|
||||
expect(instance.refs.inner.className).toBe('foo');
|
||||
});
|
||||
|
||||
it('should support refs on owned components', () => {
|
||||
const innerObj = {};
|
||||
const outerObj = {};
|
||||
|
||||
class Wrapper extends React.Component {
|
||||
getObject = () => {
|
||||
return this.props.object;
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
class Component extends React.Component {
|
||||
render() {
|
||||
const inner = <Wrapper object={innerObj} ref="inner" />;
|
||||
const outer = (
|
||||
<Wrapper object={outerObj} ref="outer">
|
||||
{inner}
|
||||
</Wrapper>
|
||||
);
|
||||
return outer;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
expect(this.refs.inner.getObject()).toEqual(innerObj);
|
||||
expect(this.refs.outer.getObject()).toEqual(outerObj);
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
});
|
||||
|
||||
it('should support callback-style refs', () => {
|
||||
const innerObj = {};
|
||||
const outerObj = {};
|
||||
|
||||
class Wrapper extends React.Component {
|
||||
getObject = () => {
|
||||
return this.props.object;
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
let mounted = false;
|
||||
|
||||
class Component extends React.Component {
|
||||
render() {
|
||||
const inner = (
|
||||
<Wrapper object={innerObj} ref={c => (this.innerRef = c)} />
|
||||
);
|
||||
const outer = (
|
||||
<Wrapper object={outerObj} ref={c => (this.outerRef = c)}>
|
||||
{inner}
|
||||
</Wrapper>
|
||||
);
|
||||
return outer;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
expect(this.innerRef.getObject()).toEqual(innerObj);
|
||||
expect(this.outerRef.getObject()).toEqual(outerObj);
|
||||
mounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
expect(mounted).toBe(true);
|
||||
});
|
||||
|
||||
// Not supported.
|
||||
xit('should support object-style refs', () => {
|
||||
const innerObj = {};
|
||||
const outerObj = {};
|
||||
|
||||
class Wrapper extends React.Component {
|
||||
getObject = () => {
|
||||
return this.props.object;
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
let mounted = false;
|
||||
|
||||
class Component extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.innerRef = React.createRef();
|
||||
this.outerRef = React.createRef();
|
||||
}
|
||||
render() {
|
||||
const inner = <Wrapper object={innerObj} ref={this.innerRef} />;
|
||||
const outer = (
|
||||
<Wrapper object={outerObj} ref={this.outerRef}>
|
||||
{inner}
|
||||
</Wrapper>
|
||||
);
|
||||
return outer;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
expect(this.innerRef.current.getObject()).toEqual(innerObj);
|
||||
expect(this.outerRef.current.getObject()).toEqual(outerObj);
|
||||
mounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
expect(mounted).toBe(true);
|
||||
});
|
||||
|
||||
it('should support new-style refs with mixed-up owners', () => {
|
||||
class Wrapper extends React.Component {
|
||||
getTitle = () => {
|
||||
return this.props.title;
|
||||
};
|
||||
|
||||
render() {
|
||||
return this.props.getContent();
|
||||
}
|
||||
}
|
||||
|
||||
let mounted = false;
|
||||
|
||||
class Component extends React.Component {
|
||||
getInner = () => {
|
||||
// (With old-style refs, it's impossible to get a ref to this div
|
||||
// because Wrapper is the current owner when this function is called.)
|
||||
return <div className="inner" ref={c => (this.innerRef = c)} />;
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Wrapper
|
||||
title="wrapper"
|
||||
ref={c => (this.wrapperRef = c)}
|
||||
getContent={this.getInner}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// Check .props.title to make sure we got the right elements back
|
||||
expect(this.wrapperRef.getTitle()).toBe('wrapper');
|
||||
expect(this.innerRef.className).toBe('inner');
|
||||
mounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
expect(mounted).toBe(true);
|
||||
});
|
||||
|
||||
it('should warn when `key` is being accessed on composite element', () => {
|
||||
const container = document.createElement('div');
|
||||
class Child extends React.Component {
|
||||
render() {
|
||||
return <div> {this.props.key} </div>;
|
||||
}
|
||||
}
|
||||
class Parent extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Child key="0" />
|
||||
<Child key="1" />
|
||||
<Child key="2" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
expect(() =>
|
||||
ReactDOM.render(<Parent />, container)
|
||||
).toErrorDev(
|
||||
'Child: `key` is not a prop. Trying to access it will result ' +
|
||||
'in `undefined` being returned. If you need to access the same ' +
|
||||
'value within the child component, you should pass it as a different ' +
|
||||
'prop. (https://reactjs.org/link/special-props)',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn when `ref` is being accessed', () => {
|
||||
const container = document.createElement('div');
|
||||
class Child extends React.Component {
|
||||
render() {
|
||||
return <div> {this.props.ref} </div>;
|
||||
}
|
||||
}
|
||||
class Parent extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Child ref="childElement" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
expect(() =>
|
||||
ReactDOM.render(<Parent />, container)
|
||||
).toErrorDev(
|
||||
'Child: `ref` is not a prop. Trying to access it will result ' +
|
||||
'in `undefined` being returned. If you need to access the same ' +
|
||||
'value within the child component, you should pass it as a different ' +
|
||||
'prop. (https://reactjs.org/link/special-props)',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
// Note: no warning before 16.
|
||||
it('should NOT warn when owner and self are different for string refs', () => {
|
||||
class ClassWithRenderProp extends React.Component {
|
||||
render() {
|
||||
return this.props.children();
|
||||
}
|
||||
}
|
||||
|
||||
class ClassParent extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<ClassWithRenderProp>{() => <div ref="myRef" />}</ClassWithRenderProp>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const container = document.createElement('div');
|
||||
ReactDOM.render(<ClassParent />, container);
|
||||
});
|
||||
149
fixtures/legacy-jsx-runtimes/react-15/yarn.lock
Normal file
149
fixtures/legacy-jsx-runtimes/react-15/yarn.lock
Normal file
@@ -0,0 +1,149 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
asap@~2.0.3:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
|
||||
|
||||
core-js@^1.0.0:
|
||||
version "1.2.7"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
|
||||
integrity sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=
|
||||
|
||||
create-react-class@^15.6.0:
|
||||
version "15.6.3"
|
||||
resolved "https://registry.yarnpkg.com/create-react-class/-/create-react-class-15.6.3.tgz#2d73237fb3f970ae6ebe011a9e66f46dbca80036"
|
||||
integrity sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==
|
||||
dependencies:
|
||||
fbjs "^0.8.9"
|
||||
loose-envify "^1.3.1"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
encoding@^0.1.11:
|
||||
version "0.1.13"
|
||||
resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9"
|
||||
integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==
|
||||
dependencies:
|
||||
iconv-lite "^0.6.2"
|
||||
|
||||
fbjs@^0.8.9:
|
||||
version "0.8.17"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
|
||||
integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=
|
||||
dependencies:
|
||||
core-js "^1.0.0"
|
||||
isomorphic-fetch "^2.1.1"
|
||||
loose-envify "^1.0.0"
|
||||
object-assign "^4.1.0"
|
||||
promise "^7.1.1"
|
||||
setimmediate "^1.0.5"
|
||||
ua-parser-js "^0.7.18"
|
||||
|
||||
iconv-lite@^0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.2.tgz#ce13d1875b0c3a674bd6a04b7f76b01b1b6ded01"
|
||||
integrity sha512-2y91h5OpQlolefMPmUlivelittSWy0rP+oYVpn6A7GwVHNE8AWzoYOBNmlwks3LobaJxgHCYZAnyNo2GgpNRNQ==
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3.0.0"
|
||||
|
||||
is-stream@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
|
||||
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
||||
|
||||
isomorphic-fetch@^2.1.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9"
|
||||
integrity sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=
|
||||
dependencies:
|
||||
node-fetch "^1.0.1"
|
||||
whatwg-fetch ">=0.10.0"
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||
dependencies:
|
||||
js-tokens "^3.0.0 || ^4.0.0"
|
||||
|
||||
node-fetch@^1.0.1:
|
||||
version "1.7.3"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
|
||||
integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==
|
||||
dependencies:
|
||||
encoding "^0.1.11"
|
||||
is-stream "^1.0.1"
|
||||
|
||||
object-assign@^4.1.0, object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
||||
|
||||
promise@^7.1.1:
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/promise/-/promise-7.3.1.tgz#064b72602b18f90f29192b8b1bc418ffd1ebd3bf"
|
||||
integrity sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==
|
||||
dependencies:
|
||||
asap "~2.0.3"
|
||||
|
||||
prop-types@^15.5.10:
|
||||
version "15.7.2"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||
dependencies:
|
||||
loose-envify "^1.4.0"
|
||||
object-assign "^4.1.1"
|
||||
react-is "^16.8.1"
|
||||
|
||||
react-dom@15:
|
||||
version "15.6.2"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.6.2.tgz#41cfadf693b757faf2708443a1d1fd5a02bef730"
|
||||
integrity sha1-Qc+t9pO3V/rycIRDodH9WgK+9zA=
|
||||
dependencies:
|
||||
fbjs "^0.8.9"
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.0"
|
||||
prop-types "^15.5.10"
|
||||
|
||||
react-is@^16.8.1:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||
|
||||
react@15:
|
||||
version "15.6.2"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-15.6.2.tgz#dba0434ab439cfe82f108f0f511663908179aa72"
|
||||
integrity sha1-26BDSrQ5z+gvEI8PURZjkIF5qnI=
|
||||
dependencies:
|
||||
create-react-class "^15.6.0"
|
||||
fbjs "^0.8.9"
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.0"
|
||||
prop-types "^15.5.10"
|
||||
|
||||
"safer-buffer@>= 2.1.2 < 3.0.0":
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||
|
||||
setimmediate@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285"
|
||||
integrity sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=
|
||||
|
||||
ua-parser-js@^0.7.18:
|
||||
version "0.7.22"
|
||||
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.22.tgz#960df60a5f911ea8f1c818f3747b99c6e177eae3"
|
||||
integrity sha512-YUxzMjJ5T71w6a8WWVcMGM6YWOTX27rCoIQgLXiWaxqXSx9D7DNjiGWn1aJIRSQ5qr0xuhra77bSIh6voR/46Q==
|
||||
|
||||
whatwg-fetch@>=0.10.0:
|
||||
version "3.4.1"
|
||||
resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.4.1.tgz#e5f871572d6879663fa5674c8f833f15a8425ab3"
|
||||
integrity sha512-sofZVzE1wKwO+EYPbWfiwzaKovWiZXf4coEzjGP9b2GBVgQRLQUZ2QcuPpQExGDAW5GItpEm6Tl4OU5mywnAoQ==
|
||||
@@ -0,0 +1,889 @@
|
||||
/** @license React v16.14.0
|
||||
* react-jsx-dev-runtime.development.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
|
||||
// ATTENTION
|
||||
// When adding new symbols to this file,
|
||||
// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
|
||||
// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
|
||||
// nor polyfill, then a plain number is used for performance.
|
||||
var REACT_ELEMENT_TYPE = 0xeac7;
|
||||
var REACT_PORTAL_TYPE = 0xeaca;
|
||||
exports.Fragment = 0xeacb;
|
||||
var REACT_STRICT_MODE_TYPE = 0xeacc;
|
||||
var REACT_PROFILER_TYPE = 0xead2;
|
||||
var REACT_PROVIDER_TYPE = 0xeacd;
|
||||
var REACT_CONTEXT_TYPE = 0xeace;
|
||||
var REACT_FORWARD_REF_TYPE = 0xead0;
|
||||
var REACT_SUSPENSE_TYPE = 0xead1;
|
||||
var REACT_SUSPENSE_LIST_TYPE = 0xead8;
|
||||
var REACT_MEMO_TYPE = 0xead3;
|
||||
var REACT_LAZY_TYPE = 0xead4;
|
||||
var REACT_BLOCK_TYPE = 0xead9;
|
||||
var REACT_SERVER_BLOCK_TYPE = 0xeada;
|
||||
var REACT_FUNDAMENTAL_TYPE = 0xead5;
|
||||
var REACT_SCOPE_TYPE = 0xead7;
|
||||
var REACT_OPAQUE_ID_TYPE = 0xeae0;
|
||||
var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1;
|
||||
var REACT_OFFSCREEN_TYPE = 0xeae2;
|
||||
var REACT_LEGACY_HIDDEN_TYPE = 0xeae3;
|
||||
|
||||
if (typeof Symbol === 'function' && Symbol.for) {
|
||||
var symbolFor = Symbol.for;
|
||||
REACT_ELEMENT_TYPE = symbolFor('react.element');
|
||||
REACT_PORTAL_TYPE = symbolFor('react.portal');
|
||||
exports.Fragment = symbolFor('react.fragment');
|
||||
REACT_STRICT_MODE_TYPE = symbolFor('react.strict_mode');
|
||||
REACT_PROFILER_TYPE = symbolFor('react.profiler');
|
||||
REACT_PROVIDER_TYPE = symbolFor('react.provider');
|
||||
REACT_CONTEXT_TYPE = symbolFor('react.context');
|
||||
REACT_FORWARD_REF_TYPE = symbolFor('react.forward_ref');
|
||||
REACT_SUSPENSE_TYPE = symbolFor('react.suspense');
|
||||
REACT_SUSPENSE_LIST_TYPE = symbolFor('react.suspense_list');
|
||||
REACT_MEMO_TYPE = symbolFor('react.memo');
|
||||
REACT_LAZY_TYPE = symbolFor('react.lazy');
|
||||
REACT_BLOCK_TYPE = symbolFor('react.block');
|
||||
REACT_SERVER_BLOCK_TYPE = symbolFor('react.server.block');
|
||||
REACT_FUNDAMENTAL_TYPE = symbolFor('react.fundamental');
|
||||
REACT_SCOPE_TYPE = symbolFor('react.scope');
|
||||
REACT_OPAQUE_ID_TYPE = symbolFor('react.opaque.id');
|
||||
REACT_DEBUG_TRACING_MODE_TYPE = symbolFor('react.debug_trace_mode');
|
||||
REACT_OFFSCREEN_TYPE = symbolFor('react.offscreen');
|
||||
REACT_LEGACY_HIDDEN_TYPE = symbolFor('react.legacy_hidden');
|
||||
}
|
||||
|
||||
var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
|
||||
var FAUX_ITERATOR_SYMBOL = '@@iterator';
|
||||
function getIteratorFn(maybeIterable) {
|
||||
if (maybeIterable === null || typeof maybeIterable !== 'object') {
|
||||
return null;
|
||||
}
|
||||
|
||||
var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
|
||||
|
||||
if (typeof maybeIterator === 'function') {
|
||||
return maybeIterator;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
||||
|
||||
function error(format) {
|
||||
{
|
||||
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
||||
args[_key2 - 1] = arguments[_key2];
|
||||
}
|
||||
|
||||
printWarning('error', format, args);
|
||||
}
|
||||
}
|
||||
|
||||
function printWarning(level, format, args) {
|
||||
// When changing this logic, you might want to also
|
||||
// update consoleWithStackDev.www.js as well.
|
||||
{
|
||||
var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
|
||||
var stack = '';
|
||||
|
||||
if (currentlyValidatingElement) {
|
||||
var name = getComponentName(currentlyValidatingElement.type);
|
||||
var owner = currentlyValidatingElement._owner;
|
||||
stack += describeComponentFrame(name, currentlyValidatingElement._source, owner && getComponentName(owner.type));
|
||||
}
|
||||
|
||||
stack += ReactDebugCurrentFrame.getStackAddendum();
|
||||
|
||||
|
||||
if (stack !== '') {
|
||||
format += '%s';
|
||||
args = args.concat([stack]);
|
||||
}
|
||||
|
||||
var argsWithFormat = args.map(function (item) {
|
||||
return '' + item;
|
||||
}); // Careful: RN currently depends on this prefix
|
||||
|
||||
argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
|
||||
// breaks IE9: https://github.com/facebook/react/issues/13610
|
||||
// eslint-disable-next-line react-internal/no-production-logging
|
||||
|
||||
Function.prototype.apply.call(console[level], console, argsWithFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// Filter certain DOM attributes (e.g. src, href) if their values are empty strings.
|
||||
|
||||
var enableScopeAPI = false; // Experimental Create Event Handle API.
|
||||
|
||||
function isValidElementType(type) {
|
||||
if (typeof type === 'string' || typeof type === 'function') {
|
||||
return true;
|
||||
} // Note: typeof might be other than 'symbol' or 'number' (e.g. if it's a polyfill).
|
||||
|
||||
|
||||
if (type === exports.Fragment || type === REACT_PROFILER_TYPE || type === REACT_DEBUG_TRACING_MODE_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || type === REACT_LEGACY_HIDDEN_TYPE || enableScopeAPI ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof type === 'object' && type !== null) {
|
||||
if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_BLOCK_TYPE || type[0] === REACT_SERVER_BLOCK_TYPE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
|
||||
function describeComponentFrame (name, source, ownerName) {
|
||||
var sourceInfo = '';
|
||||
|
||||
if (source) {
|
||||
var path = source.fileName;
|
||||
var fileName = path.replace(BEFORE_SLASH_RE, '');
|
||||
|
||||
{
|
||||
// In DEV, include code for a common special case:
|
||||
// prefer "folder/index.js" instead of just "index.js".
|
||||
if (/^index\./.test(fileName)) {
|
||||
var match = path.match(BEFORE_SLASH_RE);
|
||||
|
||||
if (match) {
|
||||
var pathBeforeSlash = match[1];
|
||||
|
||||
if (pathBeforeSlash) {
|
||||
var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
|
||||
fileName = folderName + '/' + fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
|
||||
} else if (ownerName) {
|
||||
sourceInfo = ' (created by ' + ownerName + ')';
|
||||
}
|
||||
|
||||
return '\n in ' + (name || 'Unknown') + sourceInfo;
|
||||
}
|
||||
|
||||
var Resolved = 1;
|
||||
function refineResolvedLazyComponent(lazyComponent) {
|
||||
return lazyComponent._status === Resolved ? lazyComponent._result : null;
|
||||
}
|
||||
|
||||
function getWrappedName(outerType, innerType, wrapperName) {
|
||||
var functionName = innerType.displayName || innerType.name || '';
|
||||
return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
|
||||
}
|
||||
|
||||
function getComponentName(type) {
|
||||
if (type == null) {
|
||||
// Host root, text node or just invalid type.
|
||||
return null;
|
||||
}
|
||||
|
||||
{
|
||||
if (typeof type.tag === 'number') {
|
||||
error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof type === 'function') {
|
||||
return type.displayName || type.name || null;
|
||||
}
|
||||
|
||||
if (typeof type === 'string') {
|
||||
return type;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case exports.Fragment:
|
||||
return 'Fragment';
|
||||
|
||||
case REACT_PORTAL_TYPE:
|
||||
return 'Portal';
|
||||
|
||||
case REACT_PROFILER_TYPE:
|
||||
return "Profiler";
|
||||
|
||||
case REACT_STRICT_MODE_TYPE:
|
||||
return 'StrictMode';
|
||||
|
||||
case REACT_SUSPENSE_TYPE:
|
||||
return 'Suspense';
|
||||
|
||||
case REACT_SUSPENSE_LIST_TYPE:
|
||||
return 'SuspenseList';
|
||||
}
|
||||
|
||||
if (typeof type === 'object') {
|
||||
switch (type.$$typeof) {
|
||||
case REACT_CONTEXT_TYPE:
|
||||
return 'Context.Consumer';
|
||||
|
||||
case REACT_PROVIDER_TYPE:
|
||||
return 'Context.Provider';
|
||||
|
||||
case REACT_FORWARD_REF_TYPE:
|
||||
return getWrappedName(type, type.render, 'ForwardRef');
|
||||
|
||||
case REACT_MEMO_TYPE:
|
||||
return getComponentName(type.type);
|
||||
|
||||
case REACT_BLOCK_TYPE:
|
||||
return getComponentName(type.render);
|
||||
|
||||
case REACT_LAZY_TYPE:
|
||||
{
|
||||
var thenable = type;
|
||||
var resolvedThenable = refineResolvedLazyComponent(thenable);
|
||||
|
||||
if (resolvedThenable) {
|
||||
return getComponentName(resolvedThenable);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
var loggedTypeFailures = {};
|
||||
var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
|
||||
var currentlyValidatingElement = null;
|
||||
|
||||
function setCurrentlyValidatingElement(element) {
|
||||
currentlyValidatingElement = element;
|
||||
}
|
||||
|
||||
function checkPropTypes(typeSpecs, values, location, componentName, element) {
|
||||
{
|
||||
// $FlowFixMe This is okay but Flow doesn't know it.
|
||||
var has = Function.call.bind(Object.prototype.hasOwnProperty);
|
||||
|
||||
for (var typeSpecName in typeSpecs) {
|
||||
if (has(typeSpecs, typeSpecName)) {
|
||||
var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
|
||||
// fail the render phase where it didn't fail before. So we log it.
|
||||
// After these have been cleaned up, we'll let them throw.
|
||||
|
||||
try {
|
||||
// This is intentionally an invariant that gets caught. It's the same
|
||||
// behavior as without this statement except with a better message.
|
||||
if (typeof typeSpecs[typeSpecName] !== 'function') {
|
||||
var err = Error((componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.');
|
||||
err.name = 'Invariant Violation';
|
||||
throw err;
|
||||
}
|
||||
|
||||
error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
|
||||
} catch (ex) {
|
||||
error$1 = ex;
|
||||
}
|
||||
|
||||
if (error$1 && !(error$1 instanceof Error)) {
|
||||
setCurrentlyValidatingElement(element);
|
||||
|
||||
error('%s: type specification of %s' + ' `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error$1);
|
||||
|
||||
setCurrentlyValidatingElement(null);
|
||||
}
|
||||
|
||||
if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
|
||||
// Only monitor this failure once because there tends to be a lot of the
|
||||
// same error.
|
||||
loggedTypeFailures[error$1.message] = true;
|
||||
setCurrentlyValidatingElement(element);
|
||||
|
||||
error('Failed %s type: %s', location, error$1.message);
|
||||
|
||||
setCurrentlyValidatingElement(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
var RESERVED_PROPS = {
|
||||
key: true,
|
||||
ref: true,
|
||||
__self: true,
|
||||
__source: true
|
||||
};
|
||||
var specialPropKeyWarningShown;
|
||||
var specialPropRefWarningShown;
|
||||
var didWarnAboutStringRefs;
|
||||
|
||||
{
|
||||
didWarnAboutStringRefs = {};
|
||||
}
|
||||
|
||||
function hasValidRef(config) {
|
||||
{
|
||||
if (hasOwnProperty.call(config, 'ref')) {
|
||||
var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
|
||||
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return config.ref !== undefined;
|
||||
}
|
||||
|
||||
function hasValidKey(config) {
|
||||
{
|
||||
if (hasOwnProperty.call(config, 'key')) {
|
||||
var getter = Object.getOwnPropertyDescriptor(config, 'key').get;
|
||||
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return config.key !== undefined;
|
||||
}
|
||||
|
||||
function warnIfStringRefCannotBeAutoConverted(config, self) {
|
||||
{
|
||||
if (typeof config.ref === 'string' && ReactCurrentOwner.current && self && ReactCurrentOwner.current.stateNode !== self) {
|
||||
var componentName = getComponentName(ReactCurrentOwner.current.type);
|
||||
|
||||
if (!didWarnAboutStringRefs[componentName]) {
|
||||
error('Component "%s" contains the string ref "%s". ' + 'Support for string refs will be removed in a future major release. ' + 'This case cannot be automatically converted to an arrow function. ' + 'We ask you to manually fix this case by using useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-string-ref', getComponentName(ReactCurrentOwner.current.type), config.ref);
|
||||
|
||||
didWarnAboutStringRefs[componentName] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function defineKeyPropWarningGetter(props, displayName) {
|
||||
{
|
||||
var warnAboutAccessingKey = function () {
|
||||
if (!specialPropKeyWarningShown) {
|
||||
specialPropKeyWarningShown = true;
|
||||
|
||||
error('%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);
|
||||
}
|
||||
};
|
||||
|
||||
warnAboutAccessingKey.isReactWarning = true;
|
||||
Object.defineProperty(props, 'key', {
|
||||
get: warnAboutAccessingKey,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function defineRefPropWarningGetter(props, displayName) {
|
||||
{
|
||||
var warnAboutAccessingRef = function () {
|
||||
if (!specialPropRefWarningShown) {
|
||||
specialPropRefWarningShown = true;
|
||||
|
||||
error('%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);
|
||||
}
|
||||
};
|
||||
|
||||
warnAboutAccessingRef.isReactWarning = true;
|
||||
Object.defineProperty(props, 'ref', {
|
||||
get: warnAboutAccessingRef,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Factory method to create a new React element. This no longer adheres to
|
||||
* the class pattern, so do not use new to call it. Also, instanceof check
|
||||
* will not work. Instead test $$typeof field against Symbol.for('react.element') to check
|
||||
* if something is a React Element.
|
||||
*
|
||||
* @param {*} type
|
||||
* @param {*} props
|
||||
* @param {*} key
|
||||
* @param {string|object} ref
|
||||
* @param {*} owner
|
||||
* @param {*} self A *temporary* helper to detect places where `this` is
|
||||
* different from the `owner` when React.createElement is called, so that we
|
||||
* can warn. We want to get rid of owner and replace string `ref`s with arrow
|
||||
* functions, and as long as `this` and owner are the same, there will be no
|
||||
* change in behavior.
|
||||
* @param {*} source An annotation object (added by a transpiler or otherwise)
|
||||
* indicating filename, line number, and/or other information.
|
||||
* @internal
|
||||
*/
|
||||
|
||||
|
||||
var ReactElement = function (type, key, ref, self, source, owner, props) {
|
||||
var element = {
|
||||
// This tag allows us to uniquely identify this as a React Element
|
||||
$$typeof: REACT_ELEMENT_TYPE,
|
||||
// Built-in properties that belong on the element
|
||||
type: type,
|
||||
key: key,
|
||||
ref: ref,
|
||||
props: props,
|
||||
// Record the component responsible for creating this element.
|
||||
_owner: owner
|
||||
};
|
||||
|
||||
{
|
||||
// The validation flag is currently mutative. We put it on
|
||||
// an external backing store so that we can freeze the whole object.
|
||||
// This can be replaced with a WeakMap once they are implemented in
|
||||
// commonly used development environments.
|
||||
element._store = {}; // To make comparing ReactElements easier for testing purposes, we make
|
||||
// the validation flag non-enumerable (where possible, which should
|
||||
// include every environment we run tests in), so the test framework
|
||||
// ignores it.
|
||||
|
||||
Object.defineProperty(element._store, 'validated', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
value: false
|
||||
}); // self and source are DEV only properties.
|
||||
|
||||
Object.defineProperty(element, '_self', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: self
|
||||
}); // Two elements created in two different places should be considered
|
||||
// equal for testing purposes and therefore we hide it from enumeration.
|
||||
|
||||
Object.defineProperty(element, '_source', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: source
|
||||
});
|
||||
|
||||
if (Object.freeze) {
|
||||
Object.freeze(element.props);
|
||||
Object.freeze(element);
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
};
|
||||
/**
|
||||
* https://github.com/reactjs/rfcs/pull/107
|
||||
* @param {*} type
|
||||
* @param {object} props
|
||||
* @param {string} key
|
||||
*/
|
||||
|
||||
function jsxDEV(type, config, maybeKey, source, self) {
|
||||
{
|
||||
var propName; // Reserved names are extracted
|
||||
|
||||
var props = {};
|
||||
var key = null;
|
||||
var ref = null; // Currently, key can be spread in as a prop. This causes a potential
|
||||
// issue if key is also explicitly declared (ie. <div {...props} key="Hi" />
|
||||
// or <div key="Hi" {...props} /> ). We want to deprecate key spread,
|
||||
// but as an intermediary step, we will use jsxDEV for everything except
|
||||
// <div {...props} key="Hi" />, because we aren't currently able to tell if
|
||||
// key is explicitly declared to be undefined or not.
|
||||
|
||||
if (maybeKey !== undefined) {
|
||||
key = '' + maybeKey;
|
||||
}
|
||||
|
||||
if (hasValidKey(config)) {
|
||||
key = '' + config.key;
|
||||
}
|
||||
|
||||
if (hasValidRef(config)) {
|
||||
ref = config.ref;
|
||||
warnIfStringRefCannotBeAutoConverted(config, self);
|
||||
} // Remaining properties are added to a new props object
|
||||
|
||||
|
||||
for (propName in config) {
|
||||
if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
|
||||
props[propName] = config[propName];
|
||||
}
|
||||
} // Resolve default props
|
||||
|
||||
|
||||
if (type && type.defaultProps) {
|
||||
var defaultProps = type.defaultProps;
|
||||
|
||||
for (propName in defaultProps) {
|
||||
if (props[propName] === undefined) {
|
||||
props[propName] = defaultProps[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (key || ref) {
|
||||
var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type;
|
||||
|
||||
if (key) {
|
||||
defineKeyPropWarningGetter(props, displayName);
|
||||
}
|
||||
|
||||
if (ref) {
|
||||
defineRefPropWarningGetter(props, displayName);
|
||||
}
|
||||
}
|
||||
|
||||
return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
|
||||
}
|
||||
}
|
||||
|
||||
var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
|
||||
var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
|
||||
|
||||
function setCurrentlyValidatingElement$1(element) {
|
||||
currentlyValidatingElement = element;
|
||||
}
|
||||
|
||||
var propTypesMisspellWarningShown;
|
||||
|
||||
{
|
||||
propTypesMisspellWarningShown = false;
|
||||
}
|
||||
/**
|
||||
* Verifies the object is a ReactElement.
|
||||
* See https://reactjs.org/docs/react-api.html#isvalidelement
|
||||
* @param {?object} object
|
||||
* @return {boolean} True if `object` is a ReactElement.
|
||||
* @final
|
||||
*/
|
||||
|
||||
function isValidElement(object) {
|
||||
{
|
||||
return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
function getDeclarationErrorAddendum() {
|
||||
{
|
||||
if (ReactCurrentOwner$1.current) {
|
||||
var name = getComponentName(ReactCurrentOwner$1.current.type);
|
||||
|
||||
if (name) {
|
||||
return '\n\nCheck the render method of `' + name + '`.';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceInfoErrorAddendum(source) {
|
||||
{
|
||||
if (source !== undefined) {
|
||||
var fileName = source.fileName.replace(/^.*[\\\/]/, '');
|
||||
var lineNumber = source.lineNumber;
|
||||
return '\n\nCheck your code at ' + fileName + ':' + lineNumber + '.';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Warn if there's no key explicitly set on dynamic arrays of children or
|
||||
* object keys are not valid. This allows us to keep track of children between
|
||||
* updates.
|
||||
*/
|
||||
|
||||
|
||||
var ownerHasKeyUseWarning = {};
|
||||
|
||||
function getCurrentComponentErrorInfo(parentType) {
|
||||
{
|
||||
var info = getDeclarationErrorAddendum();
|
||||
|
||||
if (!info) {
|
||||
var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;
|
||||
|
||||
if (parentName) {
|
||||
info = "\n\nCheck the top-level render call using <" + parentName + ">.";
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Warn if the element doesn't have an explicit key assigned to it.
|
||||
* This element is in an array. The array could grow and shrink or be
|
||||
* reordered. All children that haven't already been validated are required to
|
||||
* have a "key" property assigned to it. Error statuses are cached so a warning
|
||||
* will only be shown once.
|
||||
*
|
||||
* @internal
|
||||
* @param {ReactElement} element Element that requires a key.
|
||||
* @param {*} parentType element's parent's type.
|
||||
*/
|
||||
|
||||
|
||||
function validateExplicitKey(element, parentType) {
|
||||
{
|
||||
if (!element._store || element._store.validated || element.key != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
element._store.validated = true;
|
||||
var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType);
|
||||
|
||||
if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
|
||||
return;
|
||||
}
|
||||
|
||||
ownerHasKeyUseWarning[currentComponentErrorInfo] = true; // Usually the current owner is the offender, but if it accepts children as a
|
||||
// property, it may be the creator of the child that's responsible for
|
||||
// assigning it a key.
|
||||
|
||||
var childOwner = '';
|
||||
|
||||
if (element && element._owner && element._owner !== ReactCurrentOwner$1.current) {
|
||||
// Give the component that originally created this child.
|
||||
childOwner = " It was passed a child from " + getComponentName(element._owner.type) + ".";
|
||||
}
|
||||
|
||||
setCurrentlyValidatingElement$1(element);
|
||||
|
||||
error('Each child in a list should have a unique "key" prop.' + '%s%s See https://reactjs.org/link/warning-keys for more information.', currentComponentErrorInfo, childOwner);
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Ensure that every element either is passed in a static location, in an
|
||||
* array with an explicit keys property defined, or in an object literal
|
||||
* with valid key property.
|
||||
*
|
||||
* @internal
|
||||
* @param {ReactNode} node Statically passed child of any type.
|
||||
* @param {*} parentType node's parent's type.
|
||||
*/
|
||||
|
||||
|
||||
function validateChildKeys(node, parentType) {
|
||||
{
|
||||
if (typeof node !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.isArray(node)) {
|
||||
for (var i = 0; i < node.length; i++) {
|
||||
var child = node[i];
|
||||
|
||||
if (isValidElement(child)) {
|
||||
validateExplicitKey(child, parentType);
|
||||
}
|
||||
}
|
||||
} else if (isValidElement(node)) {
|
||||
// This element was passed in a valid location.
|
||||
if (node._store) {
|
||||
node._store.validated = true;
|
||||
}
|
||||
} else if (node) {
|
||||
var iteratorFn = getIteratorFn(node);
|
||||
|
||||
if (typeof iteratorFn === 'function') {
|
||||
// Entry iterators used to provide implicit keys,
|
||||
// but now we print a separate warning for them later.
|
||||
if (iteratorFn !== node.entries) {
|
||||
var iterator = iteratorFn.call(node);
|
||||
var step;
|
||||
|
||||
while (!(step = iterator.next()).done) {
|
||||
if (isValidElement(step.value)) {
|
||||
validateExplicitKey(step.value, parentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Given an element, validate that its props follow the propTypes definition,
|
||||
* provided by the type.
|
||||
*
|
||||
* @param {ReactElement} element
|
||||
*/
|
||||
|
||||
|
||||
function validatePropTypes(element) {
|
||||
{
|
||||
var type = element.type;
|
||||
|
||||
if (type === null || type === undefined || typeof type === 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
var propTypes;
|
||||
|
||||
if (typeof type === 'function') {
|
||||
propTypes = type.propTypes;
|
||||
} else if (typeof type === 'object' && (type.$$typeof === REACT_FORWARD_REF_TYPE || // Note: Memo only checks outer props here.
|
||||
// Inner props are checked in the reconciler.
|
||||
type.$$typeof === REACT_MEMO_TYPE)) {
|
||||
propTypes = type.propTypes;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (propTypes) {
|
||||
// Intentionally inside to avoid triggering lazy initializers:
|
||||
var name = getComponentName(type);
|
||||
checkPropTypes(propTypes, element.props, 'prop', name, element);
|
||||
} else if (type.PropTypes !== undefined && !propTypesMisspellWarningShown) {
|
||||
propTypesMisspellWarningShown = true; // Intentionally inside to avoid triggering lazy initializers:
|
||||
|
||||
var _name = getComponentName(type);
|
||||
|
||||
error('Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?', _name || 'Unknown');
|
||||
}
|
||||
|
||||
if (typeof type.getDefaultProps === 'function' && !type.getDefaultProps.isReactClassApproved) {
|
||||
error('getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.');
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Given a fragment, validate that it can only be provided with fragment props
|
||||
* @param {ReactElement} fragment
|
||||
*/
|
||||
|
||||
|
||||
function validateFragmentProps(fragment) {
|
||||
{
|
||||
var keys = Object.keys(fragment.props);
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
|
||||
if (key !== 'children' && key !== 'key') {
|
||||
setCurrentlyValidatingElement$1(fragment);
|
||||
|
||||
error('Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key);
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fragment.ref !== null) {
|
||||
setCurrentlyValidatingElement$1(fragment);
|
||||
|
||||
error('Invalid attribute `ref` supplied to `React.Fragment`.');
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function jsxWithValidation(type, props, key, isStaticChildren, source, self) {
|
||||
{
|
||||
var validType = isValidElementType(type); // We warn in this case but don't throw. We expect the element creation to
|
||||
// succeed and there will likely be errors in render.
|
||||
|
||||
if (!validType) {
|
||||
var info = '';
|
||||
|
||||
if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
|
||||
info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and named imports.";
|
||||
}
|
||||
|
||||
var sourceInfo = getSourceInfoErrorAddendum(source);
|
||||
|
||||
if (sourceInfo) {
|
||||
info += sourceInfo;
|
||||
} else {
|
||||
info += getDeclarationErrorAddendum();
|
||||
}
|
||||
|
||||
var typeString;
|
||||
|
||||
if (type === null) {
|
||||
typeString = 'null';
|
||||
} else if (Array.isArray(type)) {
|
||||
typeString = 'array';
|
||||
} else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {
|
||||
typeString = "<" + (getComponentName(type.type) || 'Unknown') + " />";
|
||||
info = ' Did you accidentally export a JSX literal instead of a component?';
|
||||
} else {
|
||||
typeString = typeof type;
|
||||
}
|
||||
|
||||
error('React.jsx: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', typeString, info);
|
||||
}
|
||||
|
||||
var element = jsxDEV(type, props, key, source, self); // The result can be nullish if a mock or a custom function is used.
|
||||
// TODO: Drop this when these are no longer allowed as the type argument.
|
||||
|
||||
if (element == null) {
|
||||
return element;
|
||||
} // Skip key warning if the type isn't valid since our key validation logic
|
||||
// doesn't expect a non-string/function type and can throw confusing errors.
|
||||
// We don't want exception behavior to differ between dev and prod.
|
||||
// (Rendering will throw with a helpful message and as soon as the type is
|
||||
// fixed, the key warnings will appear.)
|
||||
|
||||
|
||||
if (validType) {
|
||||
var children = props.children;
|
||||
|
||||
if (children !== undefined) {
|
||||
if (isStaticChildren) {
|
||||
if (Array.isArray(children)) {
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
validateChildKeys(children[i], type);
|
||||
}
|
||||
|
||||
if (Object.freeze) {
|
||||
Object.freeze(children);
|
||||
}
|
||||
} else {
|
||||
error('React.jsx: Static children should always be an array. ' + 'You are likely explicitly calling React.jsxs or React.jsxDEV. ' + 'Use the Babel transform instead.');
|
||||
}
|
||||
} else {
|
||||
validateChildKeys(children, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type === exports.Fragment) {
|
||||
validateFragmentProps(element);
|
||||
} else {
|
||||
validatePropTypes(element);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
} // These two functions exist to still get child warnings in dev
|
||||
|
||||
var jsxDEV$1 = jsxWithValidation ;
|
||||
|
||||
exports.jsxDEV = jsxDEV$1;
|
||||
})();
|
||||
}
|
||||
9
fixtures/legacy-jsx-runtimes/react-16/cjs/react-jsx-dev-runtime.production.min.js
vendored
Normal file
9
fixtures/legacy-jsx-runtimes/react-16/cjs/react-jsx-dev-runtime.production.min.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/** @license React v16.14.0
|
||||
* react-jsx-dev-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
'use strict';require("react");exports.Fragment=60107;if("function"===typeof Symbol&&Symbol.for){var a=Symbol.for;exports.Fragment=a("react.fragment")}exports.jsxDEV=void 0;
|
||||
@@ -0,0 +1,911 @@
|
||||
/** @license React v16.14.0
|
||||
* react-jsx-runtime.development.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV !== "production") {
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
var React = require('react');
|
||||
|
||||
// ATTENTION
|
||||
// When adding new symbols to this file,
|
||||
// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
|
||||
// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
|
||||
// nor polyfill, then a plain number is used for performance.
|
||||
var REACT_ELEMENT_TYPE = 0xeac7;
|
||||
var REACT_PORTAL_TYPE = 0xeaca;
|
||||
exports.Fragment = 0xeacb;
|
||||
var REACT_STRICT_MODE_TYPE = 0xeacc;
|
||||
var REACT_PROFILER_TYPE = 0xead2;
|
||||
var REACT_PROVIDER_TYPE = 0xeacd;
|
||||
var REACT_CONTEXT_TYPE = 0xeace;
|
||||
var REACT_FORWARD_REF_TYPE = 0xead0;
|
||||
var REACT_SUSPENSE_TYPE = 0xead1;
|
||||
var REACT_SUSPENSE_LIST_TYPE = 0xead8;
|
||||
var REACT_MEMO_TYPE = 0xead3;
|
||||
var REACT_LAZY_TYPE = 0xead4;
|
||||
var REACT_BLOCK_TYPE = 0xead9;
|
||||
var REACT_SERVER_BLOCK_TYPE = 0xeada;
|
||||
var REACT_FUNDAMENTAL_TYPE = 0xead5;
|
||||
var REACT_SCOPE_TYPE = 0xead7;
|
||||
var REACT_OPAQUE_ID_TYPE = 0xeae0;
|
||||
var REACT_DEBUG_TRACING_MODE_TYPE = 0xeae1;
|
||||
var REACT_OFFSCREEN_TYPE = 0xeae2;
|
||||
var REACT_LEGACY_HIDDEN_TYPE = 0xeae3;
|
||||
|
||||
if (typeof Symbol === 'function' && Symbol.for) {
|
||||
var symbolFor = Symbol.for;
|
||||
REACT_ELEMENT_TYPE = symbolFor('react.element');
|
||||
REACT_PORTAL_TYPE = symbolFor('react.portal');
|
||||
exports.Fragment = symbolFor('react.fragment');
|
||||
REACT_STRICT_MODE_TYPE = symbolFor('react.strict_mode');
|
||||
REACT_PROFILER_TYPE = symbolFor('react.profiler');
|
||||
REACT_PROVIDER_TYPE = symbolFor('react.provider');
|
||||
REACT_CONTEXT_TYPE = symbolFor('react.context');
|
||||
REACT_FORWARD_REF_TYPE = symbolFor('react.forward_ref');
|
||||
REACT_SUSPENSE_TYPE = symbolFor('react.suspense');
|
||||
REACT_SUSPENSE_LIST_TYPE = symbolFor('react.suspense_list');
|
||||
REACT_MEMO_TYPE = symbolFor('react.memo');
|
||||
REACT_LAZY_TYPE = symbolFor('react.lazy');
|
||||
REACT_BLOCK_TYPE = symbolFor('react.block');
|
||||
REACT_SERVER_BLOCK_TYPE = symbolFor('react.server.block');
|
||||
REACT_FUNDAMENTAL_TYPE = symbolFor('react.fundamental');
|
||||
REACT_SCOPE_TYPE = symbolFor('react.scope');
|
||||
REACT_OPAQUE_ID_TYPE = symbolFor('react.opaque.id');
|
||||
REACT_DEBUG_TRACING_MODE_TYPE = symbolFor('react.debug_trace_mode');
|
||||
REACT_OFFSCREEN_TYPE = symbolFor('react.offscreen');
|
||||
REACT_LEGACY_HIDDEN_TYPE = symbolFor('react.legacy_hidden');
|
||||
}
|
||||
|
||||
var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
|
||||
var FAUX_ITERATOR_SYMBOL = '@@iterator';
|
||||
function getIteratorFn(maybeIterable) {
|
||||
if (maybeIterable === null || typeof maybeIterable !== 'object') {
|
||||
return null;
|
||||
}
|
||||
|
||||
var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
|
||||
|
||||
if (typeof maybeIterator === 'function') {
|
||||
return maybeIterator;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
||||
|
||||
function error(format) {
|
||||
{
|
||||
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
|
||||
args[_key2 - 1] = arguments[_key2];
|
||||
}
|
||||
|
||||
printWarning('error', format, args);
|
||||
}
|
||||
}
|
||||
|
||||
function printWarning(level, format, args) {
|
||||
// When changing this logic, you might want to also
|
||||
// update consoleWithStackDev.www.js as well.
|
||||
{
|
||||
var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
|
||||
var stack = '';
|
||||
|
||||
if (currentlyValidatingElement) {
|
||||
var name = getComponentName(currentlyValidatingElement.type);
|
||||
var owner = currentlyValidatingElement._owner;
|
||||
stack += describeComponentFrame(name, currentlyValidatingElement._source, owner && getComponentName(owner.type));
|
||||
}
|
||||
|
||||
stack += ReactDebugCurrentFrame.getStackAddendum();
|
||||
|
||||
if (stack !== '') {
|
||||
format += '%s';
|
||||
args = args.concat([stack]);
|
||||
}
|
||||
|
||||
var argsWithFormat = args.map(function (item) {
|
||||
return '' + item;
|
||||
}); // Careful: RN currently depends on this prefix
|
||||
|
||||
argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
|
||||
// breaks IE9: https://github.com/facebook/react/issues/13610
|
||||
// eslint-disable-next-line react-internal/no-production-logging
|
||||
|
||||
Function.prototype.apply.call(console[level], console, argsWithFormat);
|
||||
}
|
||||
}
|
||||
|
||||
// Filter certain DOM attributes (e.g. src, href) if their values are empty strings.
|
||||
|
||||
var enableScopeAPI = false; // Experimental Create Event Handle API.
|
||||
|
||||
function isValidElementType(type) {
|
||||
if (typeof type === 'string' || typeof type === 'function') {
|
||||
return true;
|
||||
} // Note: typeof might be other than 'symbol' or 'number' (e.g. if it's a polyfill).
|
||||
|
||||
|
||||
if (type === exports.Fragment || type === REACT_PROFILER_TYPE || type === REACT_DEBUG_TRACING_MODE_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || type === REACT_LEGACY_HIDDEN_TYPE || enableScopeAPI ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (typeof type === 'object' && type !== null) {
|
||||
if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_BLOCK_TYPE || type[0] === REACT_SERVER_BLOCK_TYPE) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
|
||||
function describeComponentFrame (name, source, ownerName) {
|
||||
var sourceInfo = '';
|
||||
|
||||
if (source) {
|
||||
var path = source.fileName;
|
||||
var fileName = path.replace(BEFORE_SLASH_RE, '');
|
||||
|
||||
{
|
||||
// In DEV, include code for a common special case:
|
||||
// prefer "folder/index.js" instead of just "index.js".
|
||||
if (/^index\./.test(fileName)) {
|
||||
var match = path.match(BEFORE_SLASH_RE);
|
||||
|
||||
if (match) {
|
||||
var pathBeforeSlash = match[1];
|
||||
|
||||
if (pathBeforeSlash) {
|
||||
var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
|
||||
fileName = folderName + '/' + fileName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
|
||||
} else if (ownerName) {
|
||||
sourceInfo = ' (created by ' + ownerName + ')';
|
||||
}
|
||||
|
||||
return '\n in ' + (name || 'Unknown') + sourceInfo;
|
||||
}
|
||||
|
||||
var Resolved = 1;
|
||||
function refineResolvedLazyComponent(lazyComponent) {
|
||||
return lazyComponent._status === Resolved ? lazyComponent._result : null;
|
||||
}
|
||||
|
||||
function getWrappedName(outerType, innerType, wrapperName) {
|
||||
var functionName = innerType.displayName || innerType.name || '';
|
||||
return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
|
||||
}
|
||||
|
||||
function getComponentName(type) {
|
||||
if (type == null) {
|
||||
// Host root, text node or just invalid type.
|
||||
return null;
|
||||
}
|
||||
|
||||
{
|
||||
if (typeof type.tag === 'number') {
|
||||
error('Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof type === 'function') {
|
||||
return type.displayName || type.name || null;
|
||||
}
|
||||
|
||||
if (typeof type === 'string') {
|
||||
return type;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case exports.Fragment:
|
||||
return 'Fragment';
|
||||
|
||||
case REACT_PORTAL_TYPE:
|
||||
return 'Portal';
|
||||
|
||||
case REACT_PROFILER_TYPE:
|
||||
return "Profiler";
|
||||
|
||||
case REACT_STRICT_MODE_TYPE:
|
||||
return 'StrictMode';
|
||||
|
||||
case REACT_SUSPENSE_TYPE:
|
||||
return 'Suspense';
|
||||
|
||||
case REACT_SUSPENSE_LIST_TYPE:
|
||||
return 'SuspenseList';
|
||||
}
|
||||
|
||||
if (typeof type === 'object') {
|
||||
switch (type.$$typeof) {
|
||||
case REACT_CONTEXT_TYPE:
|
||||
return 'Context.Consumer';
|
||||
|
||||
case REACT_PROVIDER_TYPE:
|
||||
return 'Context.Provider';
|
||||
|
||||
case REACT_FORWARD_REF_TYPE:
|
||||
return getWrappedName(type, type.render, 'ForwardRef');
|
||||
|
||||
case REACT_MEMO_TYPE:
|
||||
return getComponentName(type.type);
|
||||
|
||||
case REACT_BLOCK_TYPE:
|
||||
return getComponentName(type.render);
|
||||
|
||||
case REACT_LAZY_TYPE:
|
||||
{
|
||||
var thenable = type;
|
||||
var resolvedThenable = refineResolvedLazyComponent(thenable);
|
||||
|
||||
if (resolvedThenable) {
|
||||
return getComponentName(resolvedThenable);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
var loggedTypeFailures = {};
|
||||
var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
|
||||
var currentlyValidatingElement = null;
|
||||
|
||||
function setCurrentlyValidatingElement(element) {
|
||||
{
|
||||
currentlyValidatingElement = element;
|
||||
}
|
||||
}
|
||||
|
||||
function checkPropTypes(typeSpecs, values, location, componentName, element) {
|
||||
{
|
||||
// $FlowFixMe This is okay but Flow doesn't know it.
|
||||
var has = Function.call.bind(Object.prototype.hasOwnProperty);
|
||||
|
||||
for (var typeSpecName in typeSpecs) {
|
||||
if (has(typeSpecs, typeSpecName)) {
|
||||
var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
|
||||
// fail the render phase where it didn't fail before. So we log it.
|
||||
// After these have been cleaned up, we'll let them throw.
|
||||
|
||||
try {
|
||||
// This is intentionally an invariant that gets caught. It's the same
|
||||
// behavior as without this statement except with a better message.
|
||||
if (typeof typeSpecs[typeSpecName] !== 'function') {
|
||||
var err = Error((componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.');
|
||||
err.name = 'Invariant Violation';
|
||||
throw err;
|
||||
}
|
||||
|
||||
error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
|
||||
} catch (ex) {
|
||||
error$1 = ex;
|
||||
}
|
||||
|
||||
if (error$1 && !(error$1 instanceof Error)) {
|
||||
setCurrentlyValidatingElement(element);
|
||||
|
||||
error('%s: type specification of %s' + ' `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error$1);
|
||||
|
||||
setCurrentlyValidatingElement(null);
|
||||
}
|
||||
|
||||
if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
|
||||
// Only monitor this failure once because there tends to be a lot of the
|
||||
// same error.
|
||||
loggedTypeFailures[error$1.message] = true;
|
||||
setCurrentlyValidatingElement(element);
|
||||
|
||||
error('Failed %s type: %s', location, error$1.message);
|
||||
|
||||
setCurrentlyValidatingElement(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
|
||||
var hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
var RESERVED_PROPS = {
|
||||
key: true,
|
||||
ref: true,
|
||||
__self: true,
|
||||
__source: true
|
||||
};
|
||||
var specialPropKeyWarningShown;
|
||||
var specialPropRefWarningShown;
|
||||
var didWarnAboutStringRefs;
|
||||
|
||||
{
|
||||
didWarnAboutStringRefs = {};
|
||||
}
|
||||
|
||||
function hasValidRef(config) {
|
||||
{
|
||||
if (hasOwnProperty.call(config, 'ref')) {
|
||||
var getter = Object.getOwnPropertyDescriptor(config, 'ref').get;
|
||||
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return config.ref !== undefined;
|
||||
}
|
||||
|
||||
function hasValidKey(config) {
|
||||
{
|
||||
if (hasOwnProperty.call(config, 'key')) {
|
||||
var getter = Object.getOwnPropertyDescriptor(config, 'key').get;
|
||||
|
||||
if (getter && getter.isReactWarning) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return config.key !== undefined;
|
||||
}
|
||||
|
||||
function warnIfStringRefCannotBeAutoConverted(config, self) {
|
||||
{
|
||||
if (typeof config.ref === 'string' && ReactCurrentOwner.current && self && ReactCurrentOwner.current.stateNode !== self) {
|
||||
var componentName = getComponentName(ReactCurrentOwner.current.type);
|
||||
|
||||
if (!didWarnAboutStringRefs[componentName]) {
|
||||
error('Component "%s" contains the string ref "%s". ' + 'Support for string refs will be removed in a future major release. ' + 'This case cannot be automatically converted to an arrow function. ' + 'We ask you to manually fix this case by using useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-string-ref', getComponentName(ReactCurrentOwner.current.type), config.ref);
|
||||
|
||||
didWarnAboutStringRefs[componentName] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function defineKeyPropWarningGetter(props, displayName) {
|
||||
{
|
||||
var warnAboutAccessingKey = function () {
|
||||
if (!specialPropKeyWarningShown) {
|
||||
specialPropKeyWarningShown = true;
|
||||
|
||||
error('%s: `key` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);
|
||||
}
|
||||
};
|
||||
|
||||
warnAboutAccessingKey.isReactWarning = true;
|
||||
Object.defineProperty(props, 'key', {
|
||||
get: warnAboutAccessingKey,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function defineRefPropWarningGetter(props, displayName) {
|
||||
{
|
||||
var warnAboutAccessingRef = function () {
|
||||
if (!specialPropRefWarningShown) {
|
||||
specialPropRefWarningShown = true;
|
||||
|
||||
error('%s: `ref` is not a prop. Trying to access it will result ' + 'in `undefined` being returned. If you need to access the same ' + 'value within the child component, you should pass it as a different ' + 'prop. (https://reactjs.org/link/special-props)', displayName);
|
||||
}
|
||||
};
|
||||
|
||||
warnAboutAccessingRef.isReactWarning = true;
|
||||
Object.defineProperty(props, 'ref', {
|
||||
get: warnAboutAccessingRef,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Factory method to create a new React element. This no longer adheres to
|
||||
* the class pattern, so do not use new to call it. Also, instanceof check
|
||||
* will not work. Instead test $$typeof field against Symbol.for('react.element') to check
|
||||
* if something is a React Element.
|
||||
*
|
||||
* @param {*} type
|
||||
* @param {*} props
|
||||
* @param {*} key
|
||||
* @param {string|object} ref
|
||||
* @param {*} owner
|
||||
* @param {*} self A *temporary* helper to detect places where `this` is
|
||||
* different from the `owner` when React.createElement is called, so that we
|
||||
* can warn. We want to get rid of owner and replace string `ref`s with arrow
|
||||
* functions, and as long as `this` and owner are the same, there will be no
|
||||
* change in behavior.
|
||||
* @param {*} source An annotation object (added by a transpiler or otherwise)
|
||||
* indicating filename, line number, and/or other information.
|
||||
* @internal
|
||||
*/
|
||||
|
||||
|
||||
var ReactElement = function (type, key, ref, self, source, owner, props) {
|
||||
var element = {
|
||||
// This tag allows us to uniquely identify this as a React Element
|
||||
$$typeof: REACT_ELEMENT_TYPE,
|
||||
// Built-in properties that belong on the element
|
||||
type: type,
|
||||
key: key,
|
||||
ref: ref,
|
||||
props: props,
|
||||
// Record the component responsible for creating this element.
|
||||
_owner: owner
|
||||
};
|
||||
|
||||
{
|
||||
// The validation flag is currently mutative. We put it on
|
||||
// an external backing store so that we can freeze the whole object.
|
||||
// This can be replaced with a WeakMap once they are implemented in
|
||||
// commonly used development environments.
|
||||
element._store = {}; // To make comparing ReactElements easier for testing purposes, we make
|
||||
// the validation flag non-enumerable (where possible, which should
|
||||
// include every environment we run tests in), so the test framework
|
||||
// ignores it.
|
||||
|
||||
Object.defineProperty(element._store, 'validated', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
value: false
|
||||
}); // self and source are DEV only properties.
|
||||
|
||||
Object.defineProperty(element, '_self', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: self
|
||||
}); // Two elements created in two different places should be considered
|
||||
// equal for testing purposes and therefore we hide it from enumeration.
|
||||
|
||||
Object.defineProperty(element, '_source', {
|
||||
configurable: false,
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: source
|
||||
});
|
||||
|
||||
if (Object.freeze) {
|
||||
Object.freeze(element.props);
|
||||
Object.freeze(element);
|
||||
}
|
||||
}
|
||||
|
||||
return element;
|
||||
};
|
||||
/**
|
||||
* https://github.com/reactjs/rfcs/pull/107
|
||||
* @param {*} type
|
||||
* @param {object} props
|
||||
* @param {string} key
|
||||
*/
|
||||
|
||||
function jsxDEV(type, config, maybeKey, source, self) {
|
||||
{
|
||||
var propName; // Reserved names are extracted
|
||||
|
||||
var props = {};
|
||||
var key = null;
|
||||
var ref = null; // Currently, key can be spread in as a prop. This causes a potential
|
||||
// issue if key is also explicitly declared (ie. <div {...props} key="Hi" />
|
||||
// or <div key="Hi" {...props} /> ). We want to deprecate key spread,
|
||||
// but as an intermediary step, we will use jsxDEV for everything except
|
||||
// <div {...props} key="Hi" />, because we aren't currently able to tell if
|
||||
// key is explicitly declared to be undefined or not.
|
||||
|
||||
if (maybeKey !== undefined) {
|
||||
key = '' + maybeKey;
|
||||
}
|
||||
|
||||
if (hasValidKey(config)) {
|
||||
key = '' + config.key;
|
||||
}
|
||||
|
||||
if (hasValidRef(config)) {
|
||||
ref = config.ref;
|
||||
warnIfStringRefCannotBeAutoConverted(config, self);
|
||||
} // Remaining properties are added to a new props object
|
||||
|
||||
|
||||
for (propName in config) {
|
||||
if (hasOwnProperty.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) {
|
||||
props[propName] = config[propName];
|
||||
}
|
||||
} // Resolve default props
|
||||
|
||||
|
||||
if (type && type.defaultProps) {
|
||||
var defaultProps = type.defaultProps;
|
||||
|
||||
for (propName in defaultProps) {
|
||||
if (props[propName] === undefined) {
|
||||
props[propName] = defaultProps[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (key || ref) {
|
||||
var displayName = typeof type === 'function' ? type.displayName || type.name || 'Unknown' : type;
|
||||
|
||||
if (key) {
|
||||
defineKeyPropWarningGetter(props, displayName);
|
||||
}
|
||||
|
||||
if (ref) {
|
||||
defineRefPropWarningGetter(props, displayName);
|
||||
}
|
||||
}
|
||||
|
||||
return ReactElement(type, key, ref, self, source, ReactCurrentOwner.current, props);
|
||||
}
|
||||
}
|
||||
|
||||
var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
|
||||
var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
|
||||
|
||||
function setCurrentlyValidatingElement$1(element) {
|
||||
currentlyValidatingElement = element;
|
||||
}
|
||||
|
||||
var propTypesMisspellWarningShown;
|
||||
|
||||
{
|
||||
propTypesMisspellWarningShown = false;
|
||||
}
|
||||
/**
|
||||
* Verifies the object is a ReactElement.
|
||||
* See https://reactjs.org/docs/react-api.html#isvalidelement
|
||||
* @param {?object} object
|
||||
* @return {boolean} True if `object` is a ReactElement.
|
||||
* @final
|
||||
*/
|
||||
|
||||
function isValidElement(object) {
|
||||
{
|
||||
return typeof object === 'object' && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
function getDeclarationErrorAddendum() {
|
||||
{
|
||||
if (ReactCurrentOwner$1.current) {
|
||||
var name = getComponentName(ReactCurrentOwner$1.current.type);
|
||||
|
||||
if (name) {
|
||||
return '\n\nCheck the render method of `' + name + '`.';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
function getSourceInfoErrorAddendum(source) {
|
||||
{
|
||||
if (source !== undefined) {
|
||||
var fileName = source.fileName.replace(/^.*[\\\/]/, '');
|
||||
var lineNumber = source.lineNumber;
|
||||
return '\n\nCheck your code at ' + fileName + ':' + lineNumber + '.';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Warn if there's no key explicitly set on dynamic arrays of children or
|
||||
* object keys are not valid. This allows us to keep track of children between
|
||||
* updates.
|
||||
*/
|
||||
|
||||
|
||||
var ownerHasKeyUseWarning = {};
|
||||
|
||||
function getCurrentComponentErrorInfo(parentType) {
|
||||
{
|
||||
var info = getDeclarationErrorAddendum();
|
||||
|
||||
if (!info) {
|
||||
var parentName = typeof parentType === 'string' ? parentType : parentType.displayName || parentType.name;
|
||||
|
||||
if (parentName) {
|
||||
info = "\n\nCheck the top-level render call using <" + parentName + ">.";
|
||||
}
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Warn if the element doesn't have an explicit key assigned to it.
|
||||
* This element is in an array. The array could grow and shrink or be
|
||||
* reordered. All children that haven't already been validated are required to
|
||||
* have a "key" property assigned to it. Error statuses are cached so a warning
|
||||
* will only be shown once.
|
||||
*
|
||||
* @internal
|
||||
* @param {ReactElement} element Element that requires a key.
|
||||
* @param {*} parentType element's parent's type.
|
||||
*/
|
||||
|
||||
|
||||
function validateExplicitKey(element, parentType) {
|
||||
{
|
||||
if (!element._store || element._store.validated || element.key != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
element._store.validated = true;
|
||||
var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType);
|
||||
|
||||
if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
|
||||
return;
|
||||
}
|
||||
|
||||
ownerHasKeyUseWarning[currentComponentErrorInfo] = true; // Usually the current owner is the offender, but if it accepts children as a
|
||||
// property, it may be the creator of the child that's responsible for
|
||||
// assigning it a key.
|
||||
|
||||
var childOwner = '';
|
||||
|
||||
if (element && element._owner && element._owner !== ReactCurrentOwner$1.current) {
|
||||
// Give the component that originally created this child.
|
||||
childOwner = " It was passed a child from " + getComponentName(element._owner.type) + ".";
|
||||
}
|
||||
|
||||
setCurrentlyValidatingElement$1(element);
|
||||
|
||||
error('Each child in a list should have a unique "key" prop.' + '%s%s See https://reactjs.org/link/warning-keys for more information.', currentComponentErrorInfo, childOwner);
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Ensure that every element either is passed in a static location, in an
|
||||
* array with an explicit keys property defined, or in an object literal
|
||||
* with valid key property.
|
||||
*
|
||||
* @internal
|
||||
* @param {ReactNode} node Statically passed child of any type.
|
||||
* @param {*} parentType node's parent's type.
|
||||
*/
|
||||
|
||||
|
||||
function validateChildKeys(node, parentType) {
|
||||
{
|
||||
if (typeof node !== 'object') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Array.isArray(node)) {
|
||||
for (var i = 0; i < node.length; i++) {
|
||||
var child = node[i];
|
||||
|
||||
if (isValidElement(child)) {
|
||||
validateExplicitKey(child, parentType);
|
||||
}
|
||||
}
|
||||
} else if (isValidElement(node)) {
|
||||
// This element was passed in a valid location.
|
||||
if (node._store) {
|
||||
node._store.validated = true;
|
||||
}
|
||||
} else if (node) {
|
||||
var iteratorFn = getIteratorFn(node);
|
||||
|
||||
if (typeof iteratorFn === 'function') {
|
||||
// Entry iterators used to provide implicit keys,
|
||||
// but now we print a separate warning for them later.
|
||||
if (iteratorFn !== node.entries) {
|
||||
var iterator = iteratorFn.call(node);
|
||||
var step;
|
||||
|
||||
while (!(step = iterator.next()).done) {
|
||||
if (isValidElement(step.value)) {
|
||||
validateExplicitKey(step.value, parentType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Given an element, validate that its props follow the propTypes definition,
|
||||
* provided by the type.
|
||||
*
|
||||
* @param {ReactElement} element
|
||||
*/
|
||||
|
||||
|
||||
function validatePropTypes(element) {
|
||||
{
|
||||
var type = element.type;
|
||||
|
||||
if (type === null || type === undefined || typeof type === 'string') {
|
||||
return;
|
||||
}
|
||||
|
||||
var propTypes;
|
||||
|
||||
if (typeof type === 'function') {
|
||||
propTypes = type.propTypes;
|
||||
} else if (typeof type === 'object' && (type.$$typeof === REACT_FORWARD_REF_TYPE || // Note: Memo only checks outer props here.
|
||||
// Inner props are checked in the reconciler.
|
||||
type.$$typeof === REACT_MEMO_TYPE)) {
|
||||
propTypes = type.propTypes;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if (propTypes) {
|
||||
// Intentionally inside to avoid triggering lazy initializers:
|
||||
var name = getComponentName(type);
|
||||
checkPropTypes(propTypes, element.props, 'prop', name, element);
|
||||
} else if (type.PropTypes !== undefined && !propTypesMisspellWarningShown) {
|
||||
propTypesMisspellWarningShown = true; // Intentionally inside to avoid triggering lazy initializers:
|
||||
|
||||
var _name = getComponentName(type);
|
||||
|
||||
error('Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?', _name || 'Unknown');
|
||||
}
|
||||
|
||||
if (typeof type.getDefaultProps === 'function' && !type.getDefaultProps.isReactClassApproved) {
|
||||
error('getDefaultProps is only used on classic React.createClass ' + 'definitions. Use a static property named `defaultProps` instead.');
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Given a fragment, validate that it can only be provided with fragment props
|
||||
* @param {ReactElement} fragment
|
||||
*/
|
||||
|
||||
|
||||
function validateFragmentProps(fragment) {
|
||||
{
|
||||
var keys = Object.keys(fragment.props);
|
||||
|
||||
for (var i = 0; i < keys.length; i++) {
|
||||
var key = keys[i];
|
||||
|
||||
if (key !== 'children' && key !== 'key') {
|
||||
setCurrentlyValidatingElement$1(fragment);
|
||||
|
||||
error('Invalid prop `%s` supplied to `React.Fragment`. ' + 'React.Fragment can only have `key` and `children` props.', key);
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (fragment.ref !== null) {
|
||||
setCurrentlyValidatingElement$1(fragment);
|
||||
|
||||
error('Invalid attribute `ref` supplied to `React.Fragment`.');
|
||||
|
||||
setCurrentlyValidatingElement$1(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function jsxWithValidation(type, props, key, isStaticChildren, source, self) {
|
||||
{
|
||||
var validType = isValidElementType(type); // We warn in this case but don't throw. We expect the element creation to
|
||||
// succeed and there will likely be errors in render.
|
||||
|
||||
if (!validType) {
|
||||
var info = '';
|
||||
|
||||
if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
|
||||
info += ' You likely forgot to export your component from the file ' + "it's defined in, or you might have mixed up default and named imports.";
|
||||
}
|
||||
|
||||
var sourceInfo = getSourceInfoErrorAddendum(source);
|
||||
|
||||
if (sourceInfo) {
|
||||
info += sourceInfo;
|
||||
} else {
|
||||
info += getDeclarationErrorAddendum();
|
||||
}
|
||||
|
||||
var typeString;
|
||||
|
||||
if (type === null) {
|
||||
typeString = 'null';
|
||||
} else if (Array.isArray(type)) {
|
||||
typeString = 'array';
|
||||
} else if (type !== undefined && type.$$typeof === REACT_ELEMENT_TYPE) {
|
||||
typeString = "<" + (getComponentName(type.type) || 'Unknown') + " />";
|
||||
info = ' Did you accidentally export a JSX literal instead of a component?';
|
||||
} else {
|
||||
typeString = typeof type;
|
||||
}
|
||||
|
||||
error('React.jsx: type is invalid -- expected a string (for ' + 'built-in components) or a class/function (for composite ' + 'components) but got: %s.%s', typeString, info);
|
||||
}
|
||||
|
||||
var element = jsxDEV(type, props, key, source, self); // The result can be nullish if a mock or a custom function is used.
|
||||
// TODO: Drop this when these are no longer allowed as the type argument.
|
||||
|
||||
if (element == null) {
|
||||
return element;
|
||||
} // Skip key warning if the type isn't valid since our key validation logic
|
||||
// doesn't expect a non-string/function type and can throw confusing errors.
|
||||
// We don't want exception behavior to differ between dev and prod.
|
||||
// (Rendering will throw with a helpful message and as soon as the type is
|
||||
// fixed, the key warnings will appear.)
|
||||
|
||||
|
||||
if (validType) {
|
||||
var children = props.children;
|
||||
|
||||
if (children !== undefined) {
|
||||
if (isStaticChildren) {
|
||||
if (Array.isArray(children)) {
|
||||
for (var i = 0; i < children.length; i++) {
|
||||
validateChildKeys(children[i], type);
|
||||
}
|
||||
|
||||
if (Object.freeze) {
|
||||
Object.freeze(children);
|
||||
}
|
||||
} else {
|
||||
error('React.jsx: Static children should always be an array. ' + 'You are likely explicitly calling React.jsxs or React.jsxDEV. ' + 'Use the Babel transform instead.');
|
||||
}
|
||||
} else {
|
||||
validateChildKeys(children, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type === exports.Fragment) {
|
||||
validateFragmentProps(element);
|
||||
} else {
|
||||
validatePropTypes(element);
|
||||
}
|
||||
|
||||
return element;
|
||||
}
|
||||
} // These two functions exist to still get child warnings in dev
|
||||
// even with the prod transform. This means that jsxDEV is purely
|
||||
// opt-in behavior for better messages but that we won't stop
|
||||
// giving you warnings if you use production apis.
|
||||
|
||||
function jsxWithValidationStatic(type, props, key) {
|
||||
{
|
||||
return jsxWithValidation(type, props, key, true);
|
||||
}
|
||||
}
|
||||
function jsxWithValidationDynamic(type, props, key) {
|
||||
{
|
||||
return jsxWithValidation(type, props, key, false);
|
||||
}
|
||||
}
|
||||
|
||||
var jsx = jsxWithValidationDynamic ; // we may want to special case jsxs internally to take advantage of static children.
|
||||
// for now we can ship identical prod functions
|
||||
|
||||
var jsxs = jsxWithValidationStatic ;
|
||||
|
||||
exports.jsx = jsx;
|
||||
exports.jsxs = jsxs;
|
||||
})();
|
||||
}
|
||||
10
fixtures/legacy-jsx-runtimes/react-16/cjs/react-jsx-runtime.production.min.js
vendored
Normal file
10
fixtures/legacy-jsx-runtimes/react-16/cjs/react-jsx-runtime.production.min.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/** @license React v16.14.0
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
'use strict';var f=require("react"),g=60103;exports.Fragment=60107;if("function"===typeof Symbol&&Symbol.for){var h=Symbol.for;g=h("react.element");exports.Fragment=h("react.fragment")}var m=f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,n=Object.prototype.hasOwnProperty,p={key:!0,ref:!0,__self:!0,__source:!0};
|
||||
function q(c,a,k){var b,d={},e=null,l=null;void 0!==k&&(e=""+k);void 0!==a.key&&(e=""+a.key);void 0!==a.ref&&(l=a.ref);for(b in a)n.call(a,b)&&!p.hasOwnProperty(b)&&(d[b]=a[b]);if(c&&c.defaultProps)for(b in a=c.defaultProps,a)void 0===d[b]&&(d[b]=a[b]);return{$$typeof:g,type:c,key:e,ref:l,props:d,_owner:m.current}}exports.jsx=q;exports.jsxs=q;
|
||||
7
fixtures/legacy-jsx-runtimes/react-16/jsx-dev-runtime.js
vendored
Normal file
7
fixtures/legacy-jsx-runtimes/react-16/jsx-dev-runtime.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-jsx-dev-runtime.production.min.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-jsx-dev-runtime.development.js');
|
||||
}
|
||||
7
fixtures/legacy-jsx-runtimes/react-16/jsx-runtime.js
vendored
Normal file
7
fixtures/legacy-jsx-runtimes/react-16/jsx-runtime.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-jsx-runtime.production.min.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-jsx-runtime.development.js');
|
||||
}
|
||||
7
fixtures/legacy-jsx-runtimes/react-16/package.json
Normal file
7
fixtures/legacy-jsx-runtimes/react-16/package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "16",
|
||||
"react-dom": "16"
|
||||
}
|
||||
}
|
||||
773
fixtures/legacy-jsx-runtimes/react-16/react-16.test.js
Normal file
773
fixtures/legacy-jsx-runtimes/react-16/react-16.test.js
Normal file
@@ -0,0 +1,773 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails react-core
|
||||
*/
|
||||
|
||||
// These tests are based on ReactJSXElement-test,
|
||||
// ReactJSXElementValidator-test, ReactComponent-test,
|
||||
// and ReactElementJSX-test.
|
||||
|
||||
jest.mock('react/jsx-runtime', () => require('./jsx-runtime'), {virtual: true});
|
||||
jest.mock('react/jsx-dev-runtime', () => require('./jsx-dev-runtime'), {
|
||||
virtual: true,
|
||||
});
|
||||
|
||||
let React = require('react');
|
||||
let ReactDOM = require('react-dom');
|
||||
let ReactTestUtils = {
|
||||
renderIntoDocument(el) {
|
||||
const container = document.createElement('div');
|
||||
return ReactDOM.render(el, container);
|
||||
},
|
||||
};
|
||||
let PropTypes = require('prop-types');
|
||||
let Component = class Component extends React.Component {
|
||||
render() {
|
||||
return <div />;
|
||||
}
|
||||
};
|
||||
let RequiredPropComponent = class extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
};
|
||||
RequiredPropComponent.displayName = 'RequiredPropComponent';
|
||||
RequiredPropComponent.propTypes = {prop: PropTypes.string.isRequired};
|
||||
|
||||
it('works', () => {
|
||||
const container = document.createElement('div');
|
||||
ReactDOM.render(<h1>hello</h1>, container);
|
||||
expect(container.textContent).toBe('hello');
|
||||
});
|
||||
|
||||
it('returns a complete element according to spec', () => {
|
||||
const element = <Component />;
|
||||
expect(element.type).toBe(Component);
|
||||
expect(element.key).toBe(null);
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('allows a lower-case to be passed as the string type', () => {
|
||||
const element = <div />;
|
||||
expect(element.type).toBe('div');
|
||||
expect(element.key).toBe(null);
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('allows a string to be passed as the type', () => {
|
||||
const TagName = 'div';
|
||||
const element = <TagName />;
|
||||
expect(element.type).toBe('div');
|
||||
expect(element.key).toBe(null);
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('returns an immutable element', () => {
|
||||
const element = <Component />;
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
expect(() => (element.type = 'div')).toThrow();
|
||||
} else {
|
||||
expect(() => (element.type = 'div')).not.toThrow();
|
||||
}
|
||||
});
|
||||
|
||||
it('does not reuse the object that is spread into props', () => {
|
||||
const config = {foo: 1};
|
||||
const element = <Component {...config} />;
|
||||
expect(element.props.foo).toBe(1);
|
||||
config.foo = 2;
|
||||
expect(element.props.foo).toBe(1);
|
||||
});
|
||||
|
||||
it('extracts key and ref from the rest of the props', () => {
|
||||
const element = <Component key="12" ref="34" foo="56" />;
|
||||
expect(element.type).toBe(Component);
|
||||
expect(element.key).toBe('12');
|
||||
expect(element.ref).toBe('34');
|
||||
const expectation = {foo: '56'};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('coerces the key to a string', () => {
|
||||
const element = <Component key={12} foo="56" />;
|
||||
expect(element.type).toBe(Component);
|
||||
expect(element.key).toBe('12');
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {foo: '56'};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('merges JSX children onto the children prop', () => {
|
||||
const a = 1;
|
||||
const element = <Component children="text">{a}</Component>;
|
||||
expect(element.props.children).toBe(a);
|
||||
});
|
||||
|
||||
it('does not override children if no JSX children are provided', () => {
|
||||
const element = <Component children="text" />;
|
||||
expect(element.props.children).toBe('text');
|
||||
});
|
||||
|
||||
it('overrides children if null is provided as a JSX child', () => {
|
||||
const element = <Component children="text">{null}</Component>;
|
||||
expect(element.props.children).toBe(null);
|
||||
});
|
||||
|
||||
it('overrides children if undefined is provided as an argument', () => {
|
||||
const element = <Component children="text">{undefined}</Component>;
|
||||
expect(element.props.children).toBe(undefined);
|
||||
|
||||
const element2 = React.cloneElement(
|
||||
<Component children="text" />,
|
||||
{},
|
||||
undefined
|
||||
);
|
||||
expect(element2.props.children).toBe(undefined);
|
||||
});
|
||||
|
||||
it('merges JSX children onto the children prop in an array', () => {
|
||||
const a = 1;
|
||||
const b = 2;
|
||||
const c = 3;
|
||||
const element = (
|
||||
<Component>
|
||||
{a}
|
||||
{b}
|
||||
{c}
|
||||
</Component>
|
||||
);
|
||||
expect(element.props.children).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it('allows static methods to be called using the type property', () => {
|
||||
class StaticMethodComponent {
|
||||
static someStaticMethod() {
|
||||
return 'someReturnValue';
|
||||
}
|
||||
render() {
|
||||
return <div />;
|
||||
}
|
||||
}
|
||||
|
||||
const element = <StaticMethodComponent />;
|
||||
expect(element.type.someStaticMethod()).toBe('someReturnValue');
|
||||
});
|
||||
|
||||
it('identifies valid elements', () => {
|
||||
expect(React.isValidElement(<div />)).toEqual(true);
|
||||
expect(React.isValidElement(<Component />)).toEqual(true);
|
||||
|
||||
expect(React.isValidElement(null)).toEqual(false);
|
||||
expect(React.isValidElement(true)).toEqual(false);
|
||||
expect(React.isValidElement({})).toEqual(false);
|
||||
expect(React.isValidElement('string')).toEqual(false);
|
||||
expect(React.isValidElement(Component)).toEqual(false);
|
||||
expect(React.isValidElement({type: 'div', props: {}})).toEqual(false);
|
||||
});
|
||||
|
||||
it('is indistinguishable from a plain object', () => {
|
||||
const element = <div className="foo" />;
|
||||
const object = {};
|
||||
expect(element.constructor).toBe(object.constructor);
|
||||
});
|
||||
|
||||
it('should use default prop value when removing a prop', () => {
|
||||
Component.defaultProps = {fruit: 'persimmon'};
|
||||
|
||||
const container = document.createElement('div');
|
||||
const instance = ReactDOM.render(<Component fruit="mango" />, container);
|
||||
expect(instance.props.fruit).toBe('mango');
|
||||
|
||||
ReactDOM.render(<Component />, container);
|
||||
expect(instance.props.fruit).toBe('persimmon');
|
||||
});
|
||||
|
||||
it('should normalize props with default values', () => {
|
||||
class NormalizingComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
NormalizingComponent.defaultProps = {prop: 'testKey'};
|
||||
|
||||
const container = document.createElement('div');
|
||||
const instance = ReactDOM.render(<NormalizingComponent />, container);
|
||||
expect(instance.props.prop).toBe('testKey');
|
||||
|
||||
const inst2 = ReactDOM.render(
|
||||
<NormalizingComponent prop={null} />,
|
||||
container
|
||||
);
|
||||
expect(inst2.props.prop).toBe(null);
|
||||
});
|
||||
|
||||
it('warns for keys for arrays of elements in children position', () => {
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<Component>{[<Component />, <Component />]}</Component>
|
||||
)
|
||||
).toErrorDev('Each child in a list should have a unique "key" prop.');
|
||||
});
|
||||
|
||||
it('warns for keys for arrays of elements with owner info', () => {
|
||||
class InnerComponent extends React.Component {
|
||||
render() {
|
||||
return <Component>{this.props.childSet}</Component>;
|
||||
}
|
||||
}
|
||||
|
||||
class ComponentWrapper extends React.Component {
|
||||
render() {
|
||||
return <InnerComponent childSet={[<Component />, <Component />]} />;
|
||||
}
|
||||
}
|
||||
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<ComponentWrapper />)
|
||||
).toErrorDev(
|
||||
'Each child in a list should have a unique "key" prop.' +
|
||||
'\n\nCheck the render method of `InnerComponent`. ' +
|
||||
'It was passed a child from ComponentWrapper. '
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warn for arrays of elements with keys', () => {
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<Component>{[<Component key="#1" />, <Component key="#2" />]}</Component>
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warn for iterable elements with keys', () => {
|
||||
const iterable = {
|
||||
'@@iterator': function() {
|
||||
let i = 0;
|
||||
return {
|
||||
next: function() {
|
||||
const done = ++i > 2;
|
||||
return {
|
||||
value: done ? undefined : <Component key={'#' + i} />,
|
||||
done: done,
|
||||
};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component>{iterable}</Component>);
|
||||
});
|
||||
|
||||
it('does not warn for numeric keys in entry iterable as a child', () => {
|
||||
const iterable = {
|
||||
'@@iterator': function() {
|
||||
let i = 0;
|
||||
return {
|
||||
next: function() {
|
||||
const done = ++i > 2;
|
||||
return {value: done ? undefined : [i, <Component />], done: done};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
iterable.entries = iterable['@@iterator'];
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component>{iterable}</Component>);
|
||||
});
|
||||
|
||||
it('does not warn when the element is directly as children', () => {
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<Component>
|
||||
<Component />
|
||||
<Component />
|
||||
</Component>
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warn when the child array contains non-elements', () => {
|
||||
void (<Component>{[{}, {}]}</Component>);
|
||||
});
|
||||
|
||||
it('should give context for PropType errors in nested components.', () => {
|
||||
// In this test, we're making sure that if a proptype error is found in a
|
||||
// component, we give a small hint as to which parent instantiated that
|
||||
// component as per warnings about key usage in ReactElementValidator.
|
||||
function MyComp({color}) {
|
||||
return <div>My color is {color}</div>;
|
||||
}
|
||||
MyComp.propTypes = {
|
||||
color: PropTypes.string,
|
||||
};
|
||||
class ParentComp extends React.Component {
|
||||
render() {
|
||||
return <MyComp color={123} />;
|
||||
}
|
||||
}
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<ParentComp />)).toErrorDev(
|
||||
'Warning: Failed prop type: ' +
|
||||
'Invalid prop `color` of type `number` supplied to `MyComp`, ' +
|
||||
'expected `string`.\n' +
|
||||
' in MyComp (at **)\n' +
|
||||
' in ParentComp (at **)'
|
||||
);
|
||||
});
|
||||
|
||||
it('gives a helpful error when passing null, undefined, or boolean', () => {
|
||||
const Undefined = undefined;
|
||||
const Null = null;
|
||||
const True = true;
|
||||
const Div = 'div';
|
||||
expect(
|
||||
() => void (<Undefined />)
|
||||
).toErrorDev(
|
||||
'Warning: React.jsx: type is invalid -- expected a string ' +
|
||||
'(for built-in components) or a class/function (for composite ' +
|
||||
'components) but got: undefined. You likely forgot to export your ' +
|
||||
"component from the file it's defined in, or you might have mixed up " +
|
||||
'default and named imports.' +
|
||||
(process.env.BABEL_ENV === 'development'
|
||||
? '\n\nCheck your code at **.'
|
||||
: ''),
|
||||
{withoutStack: true}
|
||||
);
|
||||
expect(
|
||||
() => void (<Null />)
|
||||
).toErrorDev(
|
||||
'Warning: React.jsx: type is invalid -- expected a string ' +
|
||||
'(for built-in components) or a class/function (for composite ' +
|
||||
'components) but got: null.' +
|
||||
(process.env.BABEL_ENV === 'development'
|
||||
? '\n\nCheck your code at **.'
|
||||
: ''),
|
||||
{withoutStack: true}
|
||||
);
|
||||
expect(
|
||||
() => void (<True />)
|
||||
).toErrorDev(
|
||||
'Warning: React.jsx: type is invalid -- expected a string ' +
|
||||
'(for built-in components) or a class/function (for composite ' +
|
||||
'components) but got: boolean.' +
|
||||
(process.env.BABEL_ENV === 'development'
|
||||
? '\n\nCheck your code at **.'
|
||||
: ''),
|
||||
{withoutStack: true}
|
||||
);
|
||||
// No error expected
|
||||
void (<Div />);
|
||||
});
|
||||
|
||||
it('should check default prop values', () => {
|
||||
RequiredPropComponent.defaultProps = {prop: null};
|
||||
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<RequiredPropComponent />)
|
||||
).toErrorDev(
|
||||
'Warning: Failed prop type: The prop `prop` is marked as required in ' +
|
||||
'`RequiredPropComponent`, but its value is `null`.\n' +
|
||||
' in RequiredPropComponent (at **)'
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn on invalid prop types', () => {
|
||||
// Since there is no prevalidation step for ES6 classes, there is no hook
|
||||
// for us to issue a warning earlier than element creation when the error
|
||||
// actually occurs. Since this step is skipped in production, we should just
|
||||
// warn instead of throwing for this case.
|
||||
class NullPropTypeComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
NullPropTypeComponent.propTypes = {
|
||||
prop: null,
|
||||
};
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<NullPropTypeComponent />)
|
||||
).toErrorDev(
|
||||
'NullPropTypeComponent: prop type `prop` is invalid; it must be a ' +
|
||||
'function, usually from the `prop-types` package,'
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn on invalid context types', () => {
|
||||
class NullContextTypeComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
NullContextTypeComponent.contextTypes = {
|
||||
prop: null,
|
||||
};
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<NullContextTypeComponent />)
|
||||
).toErrorDev(
|
||||
'NullContextTypeComponent: context type `prop` is invalid; it must ' +
|
||||
'be a function, usually from the `prop-types` package,'
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn if getDefaultProps is specified on the class', () => {
|
||||
class GetDefaultPropsComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
GetDefaultPropsComponent.getDefaultProps = () => ({
|
||||
prop: 'foo',
|
||||
});
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<GetDefaultPropsComponent />)
|
||||
).toErrorDev(
|
||||
'getDefaultProps is only used on classic React.createClass definitions.' +
|
||||
' Use a static property named `defaultProps` instead.',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn if component declares PropTypes instead of propTypes', () => {
|
||||
class MisspelledPropTypesComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
MisspelledPropTypesComponent.PropTypes = {
|
||||
prop: PropTypes.string,
|
||||
};
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<MisspelledPropTypesComponent prop="hi" />
|
||||
)
|
||||
).toErrorDev(
|
||||
'Warning: Component MisspelledPropTypesComponent declared `PropTypes` ' +
|
||||
'instead of `propTypes`. Did you misspell the property assignment?',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
it('warns for fragments with illegal attributes', () => {
|
||||
class Foo extends React.Component {
|
||||
render() {
|
||||
return <React.Fragment a={1}>hello</React.Fragment>;
|
||||
}
|
||||
}
|
||||
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<Foo />)).toErrorDev(
|
||||
'Invalid prop `a` supplied to `React.Fragment`. React.Fragment ' +
|
||||
'can only have `key` and `children` props.'
|
||||
);
|
||||
});
|
||||
|
||||
it('warns for fragments with refs', () => {
|
||||
class Foo extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<React.Fragment
|
||||
ref={bar => {
|
||||
this.foo = bar;
|
||||
}}>
|
||||
hello
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<Foo />)).toErrorDev(
|
||||
'Invalid attribute `ref` supplied to `React.Fragment`.'
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warn for fragments of multiple elements without keys', () => {
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<>
|
||||
<span>1</span>
|
||||
<span>2</span>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
it('warns for fragments of multiple elements with same key', () => {
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<>
|
||||
<span key="a">1</span>
|
||||
<span key="a">2</span>
|
||||
<span key="b">3</span>
|
||||
</>
|
||||
)
|
||||
).toErrorDev('Encountered two children with the same key, `a`.', {
|
||||
withoutStack: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('does not call lazy initializers eagerly', () => {
|
||||
let didCall = false;
|
||||
const Lazy = React.lazy(() => {
|
||||
didCall = true;
|
||||
return {then() {}};
|
||||
});
|
||||
<Lazy />;
|
||||
expect(didCall).toBe(false);
|
||||
});
|
||||
|
||||
it('supports classic refs', () => {
|
||||
class Foo extends React.Component {
|
||||
render() {
|
||||
return <div className="foo" ref="inner" />;
|
||||
}
|
||||
}
|
||||
const container = document.createElement('div');
|
||||
const instance = ReactDOM.render(<Foo />, container);
|
||||
expect(instance.refs.inner.className).toBe('foo');
|
||||
});
|
||||
|
||||
it('should support refs on owned components', () => {
|
||||
const innerObj = {};
|
||||
const outerObj = {};
|
||||
|
||||
class Wrapper extends React.Component {
|
||||
getObject = () => {
|
||||
return this.props.object;
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
class Component extends React.Component {
|
||||
render() {
|
||||
const inner = <Wrapper object={innerObj} ref="inner" />;
|
||||
const outer = (
|
||||
<Wrapper object={outerObj} ref="outer">
|
||||
{inner}
|
||||
</Wrapper>
|
||||
);
|
||||
return outer;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
expect(this.refs.inner.getObject()).toEqual(innerObj);
|
||||
expect(this.refs.outer.getObject()).toEqual(outerObj);
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
});
|
||||
|
||||
it('should support callback-style refs', () => {
|
||||
const innerObj = {};
|
||||
const outerObj = {};
|
||||
|
||||
class Wrapper extends React.Component {
|
||||
getObject = () => {
|
||||
return this.props.object;
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
let mounted = false;
|
||||
|
||||
class Component extends React.Component {
|
||||
render() {
|
||||
const inner = (
|
||||
<Wrapper object={innerObj} ref={c => (this.innerRef = c)} />
|
||||
);
|
||||
const outer = (
|
||||
<Wrapper object={outerObj} ref={c => (this.outerRef = c)}>
|
||||
{inner}
|
||||
</Wrapper>
|
||||
);
|
||||
return outer;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
expect(this.innerRef.getObject()).toEqual(innerObj);
|
||||
expect(this.outerRef.getObject()).toEqual(outerObj);
|
||||
mounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
expect(mounted).toBe(true);
|
||||
});
|
||||
|
||||
it('should support object-style refs', () => {
|
||||
const innerObj = {};
|
||||
const outerObj = {};
|
||||
|
||||
class Wrapper extends React.Component {
|
||||
getObject = () => {
|
||||
return this.props.object;
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
let mounted = false;
|
||||
|
||||
class Component extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.innerRef = React.createRef();
|
||||
this.outerRef = React.createRef();
|
||||
}
|
||||
render() {
|
||||
const inner = <Wrapper object={innerObj} ref={this.innerRef} />;
|
||||
const outer = (
|
||||
<Wrapper object={outerObj} ref={this.outerRef}>
|
||||
{inner}
|
||||
</Wrapper>
|
||||
);
|
||||
return outer;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
expect(this.innerRef.current.getObject()).toEqual(innerObj);
|
||||
expect(this.outerRef.current.getObject()).toEqual(outerObj);
|
||||
mounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
expect(mounted).toBe(true);
|
||||
});
|
||||
|
||||
it('should support new-style refs with mixed-up owners', () => {
|
||||
class Wrapper extends React.Component {
|
||||
getTitle = () => {
|
||||
return this.props.title;
|
||||
};
|
||||
|
||||
render() {
|
||||
return this.props.getContent();
|
||||
}
|
||||
}
|
||||
|
||||
let mounted = false;
|
||||
|
||||
class Component extends React.Component {
|
||||
getInner = () => {
|
||||
// (With old-style refs, it's impossible to get a ref to this div
|
||||
// because Wrapper is the current owner when this function is called.)
|
||||
return <div className="inner" ref={c => (this.innerRef = c)} />;
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Wrapper
|
||||
title="wrapper"
|
||||
ref={c => (this.wrapperRef = c)}
|
||||
getContent={this.getInner}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// Check .props.title to make sure we got the right elements back
|
||||
expect(this.wrapperRef.getTitle()).toBe('wrapper');
|
||||
expect(this.innerRef.className).toBe('inner');
|
||||
mounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
expect(mounted).toBe(true);
|
||||
});
|
||||
|
||||
it('should warn when `key` is being accessed on composite element', () => {
|
||||
const container = document.createElement('div');
|
||||
class Child extends React.Component {
|
||||
render() {
|
||||
return <div> {this.props.key} </div>;
|
||||
}
|
||||
}
|
||||
class Parent extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Child key="0" />
|
||||
<Child key="1" />
|
||||
<Child key="2" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
expect(() => ReactDOM.render(<Parent />, container)).toErrorDev(
|
||||
'Child: `key` is not a prop. Trying to access it will result ' +
|
||||
'in `undefined` being returned. If you need to access the same ' +
|
||||
'value within the child component, you should pass it as a different ' +
|
||||
'prop. (https://reactjs.org/link/special-props)'
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn when `ref` is being accessed', () => {
|
||||
const container = document.createElement('div');
|
||||
class Child extends React.Component {
|
||||
render() {
|
||||
return <div> {this.props.ref} </div>;
|
||||
}
|
||||
}
|
||||
class Parent extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Child ref="childElement" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
expect(() => ReactDOM.render(<Parent />, container)).toErrorDev(
|
||||
'Child: `ref` is not a prop. Trying to access it will result ' +
|
||||
'in `undefined` being returned. If you need to access the same ' +
|
||||
'value within the child component, you should pass it as a different ' +
|
||||
'prop. (https://reactjs.org/link/special-props)'
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn when owner and self are different for string refs', () => {
|
||||
class ClassWithRenderProp extends React.Component {
|
||||
render() {
|
||||
return this.props.children();
|
||||
}
|
||||
}
|
||||
|
||||
class ClassParent extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<ClassWithRenderProp>{() => <div ref="myRef" />}</ClassWithRenderProp>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const container = document.createElement('div');
|
||||
if (process.env.BABEL_ENV === 'development') {
|
||||
expect(() => ReactDOM.render(<ClassParent />, container)).toErrorDev([
|
||||
'Warning: Component "ClassWithRenderProp" contains the string ref "myRef". ' +
|
||||
'Support for string refs will be removed in a future major release. ' +
|
||||
'This case cannot be automatically converted to an arrow function. ' +
|
||||
'We ask you to manually fix this case by using useRef() or createRef() instead. ' +
|
||||
'Learn more about using refs safely here: ' +
|
||||
'https://reactjs.org/link/strict-mode-string-ref',
|
||||
]);
|
||||
} else {
|
||||
ReactDOM.render(<ClassParent />, container);
|
||||
}
|
||||
});
|
||||
61
fixtures/legacy-jsx-runtimes/react-16/yarn.lock
Normal file
61
fixtures/legacy-jsx-runtimes/react-16/yarn.lock
Normal file
@@ -0,0 +1,61 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||
dependencies:
|
||||
js-tokens "^3.0.0 || ^4.0.0"
|
||||
|
||||
object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
||||
|
||||
prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
version "15.7.2"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||
dependencies:
|
||||
loose-envify "^1.4.0"
|
||||
object-assign "^4.1.1"
|
||||
react-is "^16.8.1"
|
||||
|
||||
react-dom@16:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.13.1.tgz#c1bd37331a0486c078ee54c4740720993b2e0e7f"
|
||||
integrity sha512-81PIMmVLnCNLO/fFOQxdQkvEq/+Hfpv24XNJfpyZhTRfO0QcmQIF/PgCa1zCOj2w1hrn12MFLyaJ/G0+Mxtfag==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
scheduler "^0.19.1"
|
||||
|
||||
react-is@^16.8.1:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||
|
||||
react@16:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.13.1.tgz#2e818822f1a9743122c063d6410d85c1e3afe48e"
|
||||
integrity sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
scheduler@^0.19.1:
|
||||
version "0.19.1"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196"
|
||||
integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
File diff suppressed because it is too large
Load Diff
9
fixtures/legacy-jsx-runtimes/react-17/cjs/react-jsx-dev-runtime.production.min.js
vendored
Normal file
9
fixtures/legacy-jsx-runtimes/react-17/cjs/react-jsx-dev-runtime.production.min.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
/** @license React v17.0.0-rc.3
|
||||
* react-jsx-dev-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
'use strict';require("object-assign");require("react");exports.Fragment=60107;if("function"===typeof Symbol&&Symbol.for){var a=Symbol.for;exports.Fragment=a("react.fragment")}exports.jsxDEV=void 0;
|
||||
File diff suppressed because it is too large
Load Diff
10
fixtures/legacy-jsx-runtimes/react-17/cjs/react-jsx-runtime.production.min.js
vendored
Normal file
10
fixtures/legacy-jsx-runtimes/react-17/cjs/react-jsx-runtime.production.min.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
/** @license React v17.0.0-rc.3
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
'use strict';require("object-assign");var f=require("react"),g=60103;exports.Fragment=60107;if("function"===typeof Symbol&&Symbol.for){var h=Symbol.for;g=h("react.element");exports.Fragment=h("react.fragment")}var m=f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,n=Object.prototype.hasOwnProperty,p={key:!0,ref:!0,__self:!0,__source:!0};
|
||||
function q(c,a,k){var b,d={},e=null,l=null;void 0!==k&&(e=""+k);void 0!==a.key&&(e=""+a.key);void 0!==a.ref&&(l=a.ref);for(b in a)n.call(a,b)&&!p.hasOwnProperty(b)&&(d[b]=a[b]);if(c&&c.defaultProps)for(b in a=c.defaultProps,a)void 0===d[b]&&(d[b]=a[b]);return{$$typeof:g,type:c,key:e,ref:l,props:d,_owner:m.current}}exports.jsx=q;exports.jsxs=q;
|
||||
7
fixtures/legacy-jsx-runtimes/react-17/jsx-dev-runtime.js
vendored
Normal file
7
fixtures/legacy-jsx-runtimes/react-17/jsx-dev-runtime.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-jsx-dev-runtime.production.min.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-jsx-dev-runtime.development.js');
|
||||
}
|
||||
7
fixtures/legacy-jsx-runtimes/react-17/jsx-runtime.js
vendored
Normal file
7
fixtures/legacy-jsx-runtimes/react-17/jsx-runtime.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
module.exports = require('./cjs/react-jsx-runtime.production.min.js');
|
||||
} else {
|
||||
module.exports = require('./cjs/react-jsx-runtime.development.js');
|
||||
}
|
||||
7
fixtures/legacy-jsx-runtimes/react-17/package.json
Normal file
7
fixtures/legacy-jsx-runtimes/react-17/package.json
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "17.0.0-rc.3",
|
||||
"react-dom": "17.0.0-rc.3"
|
||||
}
|
||||
}
|
||||
773
fixtures/legacy-jsx-runtimes/react-17/react-17.test.js
Normal file
773
fixtures/legacy-jsx-runtimes/react-17/react-17.test.js
Normal file
@@ -0,0 +1,773 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails react-core
|
||||
*/
|
||||
|
||||
// These tests are based on ReactJSXElement-test,
|
||||
// ReactJSXElementValidator-test, ReactComponent-test,
|
||||
// and ReactElementJSX-test.
|
||||
|
||||
jest.mock('react/jsx-runtime', () => require('./jsx-runtime'), {virtual: true});
|
||||
jest.mock('react/jsx-dev-runtime', () => require('./jsx-dev-runtime'), {
|
||||
virtual: true,
|
||||
});
|
||||
|
||||
let React = require('react');
|
||||
let ReactDOM = require('react-dom');
|
||||
let ReactTestUtils = {
|
||||
renderIntoDocument(el) {
|
||||
const container = document.createElement('div');
|
||||
return ReactDOM.render(el, container);
|
||||
},
|
||||
};
|
||||
let PropTypes = require('prop-types');
|
||||
let Component = class Component extends React.Component {
|
||||
render() {
|
||||
return <div />;
|
||||
}
|
||||
};
|
||||
let RequiredPropComponent = class extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
};
|
||||
RequiredPropComponent.displayName = 'RequiredPropComponent';
|
||||
RequiredPropComponent.propTypes = {prop: PropTypes.string.isRequired};
|
||||
|
||||
it('works', () => {
|
||||
const container = document.createElement('div');
|
||||
ReactDOM.render(<h1>hello</h1>, container);
|
||||
expect(container.textContent).toBe('hello');
|
||||
});
|
||||
|
||||
it('returns a complete element according to spec', () => {
|
||||
const element = <Component />;
|
||||
expect(element.type).toBe(Component);
|
||||
expect(element.key).toBe(null);
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('allows a lower-case to be passed as the string type', () => {
|
||||
const element = <div />;
|
||||
expect(element.type).toBe('div');
|
||||
expect(element.key).toBe(null);
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('allows a string to be passed as the type', () => {
|
||||
const TagName = 'div';
|
||||
const element = <TagName />;
|
||||
expect(element.type).toBe('div');
|
||||
expect(element.key).toBe(null);
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('returns an immutable element', () => {
|
||||
const element = <Component />;
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
expect(() => (element.type = 'div')).toThrow();
|
||||
} else {
|
||||
expect(() => (element.type = 'div')).not.toThrow();
|
||||
}
|
||||
});
|
||||
|
||||
it('does not reuse the object that is spread into props', () => {
|
||||
const config = {foo: 1};
|
||||
const element = <Component {...config} />;
|
||||
expect(element.props.foo).toBe(1);
|
||||
config.foo = 2;
|
||||
expect(element.props.foo).toBe(1);
|
||||
});
|
||||
|
||||
it('extracts key and ref from the rest of the props', () => {
|
||||
const element = <Component key="12" ref="34" foo="56" />;
|
||||
expect(element.type).toBe(Component);
|
||||
expect(element.key).toBe('12');
|
||||
expect(element.ref).toBe('34');
|
||||
const expectation = {foo: '56'};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('coerces the key to a string', () => {
|
||||
const element = <Component key={12} foo="56" />;
|
||||
expect(element.type).toBe(Component);
|
||||
expect(element.key).toBe('12');
|
||||
expect(element.ref).toBe(null);
|
||||
const expectation = {foo: '56'};
|
||||
Object.freeze(expectation);
|
||||
expect(element.props).toEqual(expectation);
|
||||
});
|
||||
|
||||
it('merges JSX children onto the children prop', () => {
|
||||
const a = 1;
|
||||
const element = <Component children="text">{a}</Component>;
|
||||
expect(element.props.children).toBe(a);
|
||||
});
|
||||
|
||||
it('does not override children if no JSX children are provided', () => {
|
||||
const element = <Component children="text" />;
|
||||
expect(element.props.children).toBe('text');
|
||||
});
|
||||
|
||||
it('overrides children if null is provided as a JSX child', () => {
|
||||
const element = <Component children="text">{null}</Component>;
|
||||
expect(element.props.children).toBe(null);
|
||||
});
|
||||
|
||||
it('overrides children if undefined is provided as an argument', () => {
|
||||
const element = <Component children="text">{undefined}</Component>;
|
||||
expect(element.props.children).toBe(undefined);
|
||||
|
||||
const element2 = React.cloneElement(
|
||||
<Component children="text" />,
|
||||
{},
|
||||
undefined
|
||||
);
|
||||
expect(element2.props.children).toBe(undefined);
|
||||
});
|
||||
|
||||
it('merges JSX children onto the children prop in an array', () => {
|
||||
const a = 1;
|
||||
const b = 2;
|
||||
const c = 3;
|
||||
const element = (
|
||||
<Component>
|
||||
{a}
|
||||
{b}
|
||||
{c}
|
||||
</Component>
|
||||
);
|
||||
expect(element.props.children).toEqual([1, 2, 3]);
|
||||
});
|
||||
|
||||
it('allows static methods to be called using the type property', () => {
|
||||
class StaticMethodComponent {
|
||||
static someStaticMethod() {
|
||||
return 'someReturnValue';
|
||||
}
|
||||
render() {
|
||||
return <div />;
|
||||
}
|
||||
}
|
||||
|
||||
const element = <StaticMethodComponent />;
|
||||
expect(element.type.someStaticMethod()).toBe('someReturnValue');
|
||||
});
|
||||
|
||||
it('identifies valid elements', () => {
|
||||
expect(React.isValidElement(<div />)).toEqual(true);
|
||||
expect(React.isValidElement(<Component />)).toEqual(true);
|
||||
|
||||
expect(React.isValidElement(null)).toEqual(false);
|
||||
expect(React.isValidElement(true)).toEqual(false);
|
||||
expect(React.isValidElement({})).toEqual(false);
|
||||
expect(React.isValidElement('string')).toEqual(false);
|
||||
expect(React.isValidElement(Component)).toEqual(false);
|
||||
expect(React.isValidElement({type: 'div', props: {}})).toEqual(false);
|
||||
});
|
||||
|
||||
it('is indistinguishable from a plain object', () => {
|
||||
const element = <div className="foo" />;
|
||||
const object = {};
|
||||
expect(element.constructor).toBe(object.constructor);
|
||||
});
|
||||
|
||||
it('should use default prop value when removing a prop', () => {
|
||||
Component.defaultProps = {fruit: 'persimmon'};
|
||||
|
||||
const container = document.createElement('div');
|
||||
const instance = ReactDOM.render(<Component fruit="mango" />, container);
|
||||
expect(instance.props.fruit).toBe('mango');
|
||||
|
||||
ReactDOM.render(<Component />, container);
|
||||
expect(instance.props.fruit).toBe('persimmon');
|
||||
});
|
||||
|
||||
it('should normalize props with default values', () => {
|
||||
class NormalizingComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
NormalizingComponent.defaultProps = {prop: 'testKey'};
|
||||
|
||||
const container = document.createElement('div');
|
||||
const instance = ReactDOM.render(<NormalizingComponent />, container);
|
||||
expect(instance.props.prop).toBe('testKey');
|
||||
|
||||
const inst2 = ReactDOM.render(
|
||||
<NormalizingComponent prop={null} />,
|
||||
container
|
||||
);
|
||||
expect(inst2.props.prop).toBe(null);
|
||||
});
|
||||
|
||||
it('warns for keys for arrays of elements in children position', () => {
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<Component>{[<Component />, <Component />]}</Component>
|
||||
)
|
||||
).toErrorDev('Each child in a list should have a unique "key" prop.');
|
||||
});
|
||||
|
||||
it('warns for keys for arrays of elements with owner info', () => {
|
||||
class InnerComponent extends React.Component {
|
||||
render() {
|
||||
return <Component>{this.props.childSet}</Component>;
|
||||
}
|
||||
}
|
||||
|
||||
class ComponentWrapper extends React.Component {
|
||||
render() {
|
||||
return <InnerComponent childSet={[<Component />, <Component />]} />;
|
||||
}
|
||||
}
|
||||
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<ComponentWrapper />)
|
||||
).toErrorDev(
|
||||
'Each child in a list should have a unique "key" prop.' +
|
||||
'\n\nCheck the render method of `InnerComponent`. ' +
|
||||
'It was passed a child from ComponentWrapper. '
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warn for arrays of elements with keys', () => {
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<Component>{[<Component key="#1" />, <Component key="#2" />]}</Component>
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warn for iterable elements with keys', () => {
|
||||
const iterable = {
|
||||
'@@iterator': function() {
|
||||
let i = 0;
|
||||
return {
|
||||
next: function() {
|
||||
const done = ++i > 2;
|
||||
return {
|
||||
value: done ? undefined : <Component key={'#' + i} />,
|
||||
done: done,
|
||||
};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component>{iterable}</Component>);
|
||||
});
|
||||
|
||||
it('does not warn for numeric keys in entry iterable as a child', () => {
|
||||
const iterable = {
|
||||
'@@iterator': function() {
|
||||
let i = 0;
|
||||
return {
|
||||
next: function() {
|
||||
const done = ++i > 2;
|
||||
return {value: done ? undefined : [i, <Component />], done: done};
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
iterable.entries = iterable['@@iterator'];
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component>{iterable}</Component>);
|
||||
});
|
||||
|
||||
it('does not warn when the element is directly as children', () => {
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<Component>
|
||||
<Component />
|
||||
<Component />
|
||||
</Component>
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warn when the child array contains non-elements', () => {
|
||||
void (<Component>{[{}, {}]}</Component>);
|
||||
});
|
||||
|
||||
it('should give context for PropType errors in nested components.', () => {
|
||||
// In this test, we're making sure that if a proptype error is found in a
|
||||
// component, we give a small hint as to which parent instantiated that
|
||||
// component as per warnings about key usage in ReactElementValidator.
|
||||
function MyComp({color}) {
|
||||
return <div>My color is {color}</div>;
|
||||
}
|
||||
MyComp.propTypes = {
|
||||
color: PropTypes.string,
|
||||
};
|
||||
class ParentComp extends React.Component {
|
||||
render() {
|
||||
return <MyComp color={123} />;
|
||||
}
|
||||
}
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<ParentComp />)).toErrorDev(
|
||||
'Warning: Failed prop type: ' +
|
||||
'Invalid prop `color` of type `number` supplied to `MyComp`, ' +
|
||||
'expected `string`.\n' +
|
||||
' in color (at **)\n' +
|
||||
' in ParentComp (at **)'
|
||||
);
|
||||
});
|
||||
|
||||
it('gives a helpful error when passing null, undefined, or boolean', () => {
|
||||
const Undefined = undefined;
|
||||
const Null = null;
|
||||
const True = true;
|
||||
const Div = 'div';
|
||||
expect(
|
||||
() => void (<Undefined />)
|
||||
).toErrorDev(
|
||||
'Warning: React.jsx: type is invalid -- expected a string ' +
|
||||
'(for built-in components) or a class/function (for composite ' +
|
||||
'components) but got: undefined. You likely forgot to export your ' +
|
||||
"component from the file it's defined in, or you might have mixed up " +
|
||||
'default and named imports.' +
|
||||
(process.env.BABEL_ENV === 'development'
|
||||
? '\n\nCheck your code at **.'
|
||||
: ''),
|
||||
{withoutStack: true}
|
||||
);
|
||||
expect(
|
||||
() => void (<Null />)
|
||||
).toErrorDev(
|
||||
'Warning: React.jsx: type is invalid -- expected a string ' +
|
||||
'(for built-in components) or a class/function (for composite ' +
|
||||
'components) but got: null.' +
|
||||
(process.env.BABEL_ENV === 'development'
|
||||
? '\n\nCheck your code at **.'
|
||||
: ''),
|
||||
{withoutStack: true}
|
||||
);
|
||||
expect(
|
||||
() => void (<True />)
|
||||
).toErrorDev(
|
||||
'Warning: React.jsx: type is invalid -- expected a string ' +
|
||||
'(for built-in components) or a class/function (for composite ' +
|
||||
'components) but got: boolean.' +
|
||||
(process.env.BABEL_ENV === 'development'
|
||||
? '\n\nCheck your code at **.'
|
||||
: ''),
|
||||
{withoutStack: true}
|
||||
);
|
||||
// No error expected
|
||||
void (<Div />);
|
||||
});
|
||||
|
||||
it('should check default prop values', () => {
|
||||
RequiredPropComponent.defaultProps = {prop: null};
|
||||
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<RequiredPropComponent />)
|
||||
).toErrorDev(
|
||||
'Warning: Failed prop type: The prop `prop` is marked as required in ' +
|
||||
'`RequiredPropComponent`, but its value is `null`.\n' +
|
||||
' in RequiredPropComponent (at **)'
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn on invalid prop types', () => {
|
||||
// Since there is no prevalidation step for ES6 classes, there is no hook
|
||||
// for us to issue a warning earlier than element creation when the error
|
||||
// actually occurs. Since this step is skipped in production, we should just
|
||||
// warn instead of throwing for this case.
|
||||
class NullPropTypeComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
NullPropTypeComponent.propTypes = {
|
||||
prop: null,
|
||||
};
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<NullPropTypeComponent />)
|
||||
).toErrorDev(
|
||||
'NullPropTypeComponent: prop type `prop` is invalid; it must be a ' +
|
||||
'function, usually from the `prop-types` package,'
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn on invalid context types', () => {
|
||||
class NullContextTypeComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
NullContextTypeComponent.contextTypes = {
|
||||
prop: null,
|
||||
};
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<NullContextTypeComponent />)
|
||||
).toErrorDev(
|
||||
'NullContextTypeComponent: context type `prop` is invalid; it must ' +
|
||||
'be a function, usually from the `prop-types` package,'
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn if getDefaultProps is specified on the class', () => {
|
||||
class GetDefaultPropsComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
GetDefaultPropsComponent.getDefaultProps = () => ({
|
||||
prop: 'foo',
|
||||
});
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(<GetDefaultPropsComponent />)
|
||||
).toErrorDev(
|
||||
'getDefaultProps is only used on classic React.createClass definitions.' +
|
||||
' Use a static property named `defaultProps` instead.',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn if component declares PropTypes instead of propTypes', () => {
|
||||
class MisspelledPropTypesComponent extends React.Component {
|
||||
render() {
|
||||
return <span>{this.props.prop}</span>;
|
||||
}
|
||||
}
|
||||
MisspelledPropTypesComponent.PropTypes = {
|
||||
prop: PropTypes.string,
|
||||
};
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<MisspelledPropTypesComponent prop="hi" />
|
||||
)
|
||||
).toErrorDev(
|
||||
'Warning: Component MisspelledPropTypesComponent declared `PropTypes` ' +
|
||||
'instead of `propTypes`. Did you misspell the property assignment?',
|
||||
{withoutStack: true}
|
||||
);
|
||||
});
|
||||
|
||||
it('warns for fragments with illegal attributes', () => {
|
||||
class Foo extends React.Component {
|
||||
render() {
|
||||
return <React.Fragment a={1}>hello</React.Fragment>;
|
||||
}
|
||||
}
|
||||
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<Foo />)).toErrorDev(
|
||||
'Invalid prop `a` supplied to `React.Fragment`. React.Fragment ' +
|
||||
'can only have `key` and `children` props.'
|
||||
);
|
||||
});
|
||||
|
||||
it('warns for fragments with refs', () => {
|
||||
class Foo extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<React.Fragment
|
||||
ref={bar => {
|
||||
this.foo = bar;
|
||||
}}>
|
||||
hello
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
expect(() => ReactTestUtils.renderIntoDocument(<Foo />)).toErrorDev(
|
||||
'Invalid attribute `ref` supplied to `React.Fragment`.'
|
||||
);
|
||||
});
|
||||
|
||||
it('does not warn for fragments of multiple elements without keys', () => {
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<>
|
||||
<span>1</span>
|
||||
<span>2</span>
|
||||
</>
|
||||
);
|
||||
});
|
||||
|
||||
it('warns for fragments of multiple elements with same key', () => {
|
||||
expect(() =>
|
||||
ReactTestUtils.renderIntoDocument(
|
||||
<>
|
||||
<span key="a">1</span>
|
||||
<span key="a">2</span>
|
||||
<span key="b">3</span>
|
||||
</>
|
||||
)
|
||||
).toErrorDev('Encountered two children with the same key, `a`.', {
|
||||
withoutStack: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('does not call lazy initializers eagerly', () => {
|
||||
let didCall = false;
|
||||
const Lazy = React.lazy(() => {
|
||||
didCall = true;
|
||||
return {then() {}};
|
||||
});
|
||||
<Lazy />;
|
||||
expect(didCall).toBe(false);
|
||||
});
|
||||
|
||||
it('supports classic refs', () => {
|
||||
class Foo extends React.Component {
|
||||
render() {
|
||||
return <div className="foo" ref="inner" />;
|
||||
}
|
||||
}
|
||||
const container = document.createElement('div');
|
||||
const instance = ReactDOM.render(<Foo />, container);
|
||||
expect(instance.refs.inner.className).toBe('foo');
|
||||
});
|
||||
|
||||
it('should support refs on owned components', () => {
|
||||
const innerObj = {};
|
||||
const outerObj = {};
|
||||
|
||||
class Wrapper extends React.Component {
|
||||
getObject = () => {
|
||||
return this.props.object;
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
class Component extends React.Component {
|
||||
render() {
|
||||
const inner = <Wrapper object={innerObj} ref="inner" />;
|
||||
const outer = (
|
||||
<Wrapper object={outerObj} ref="outer">
|
||||
{inner}
|
||||
</Wrapper>
|
||||
);
|
||||
return outer;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
expect(this.refs.inner.getObject()).toEqual(innerObj);
|
||||
expect(this.refs.outer.getObject()).toEqual(outerObj);
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
});
|
||||
|
||||
it('should support callback-style refs', () => {
|
||||
const innerObj = {};
|
||||
const outerObj = {};
|
||||
|
||||
class Wrapper extends React.Component {
|
||||
getObject = () => {
|
||||
return this.props.object;
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
let mounted = false;
|
||||
|
||||
class Component extends React.Component {
|
||||
render() {
|
||||
const inner = (
|
||||
<Wrapper object={innerObj} ref={c => (this.innerRef = c)} />
|
||||
);
|
||||
const outer = (
|
||||
<Wrapper object={outerObj} ref={c => (this.outerRef = c)}>
|
||||
{inner}
|
||||
</Wrapper>
|
||||
);
|
||||
return outer;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
expect(this.innerRef.getObject()).toEqual(innerObj);
|
||||
expect(this.outerRef.getObject()).toEqual(outerObj);
|
||||
mounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
expect(mounted).toBe(true);
|
||||
});
|
||||
|
||||
it('should support object-style refs', () => {
|
||||
const innerObj = {};
|
||||
const outerObj = {};
|
||||
|
||||
class Wrapper extends React.Component {
|
||||
getObject = () => {
|
||||
return this.props.object;
|
||||
};
|
||||
|
||||
render() {
|
||||
return <div>{this.props.children}</div>;
|
||||
}
|
||||
}
|
||||
|
||||
let mounted = false;
|
||||
|
||||
class Component extends React.Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.innerRef = React.createRef();
|
||||
this.outerRef = React.createRef();
|
||||
}
|
||||
render() {
|
||||
const inner = <Wrapper object={innerObj} ref={this.innerRef} />;
|
||||
const outer = (
|
||||
<Wrapper object={outerObj} ref={this.outerRef}>
|
||||
{inner}
|
||||
</Wrapper>
|
||||
);
|
||||
return outer;
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
expect(this.innerRef.current.getObject()).toEqual(innerObj);
|
||||
expect(this.outerRef.current.getObject()).toEqual(outerObj);
|
||||
mounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
expect(mounted).toBe(true);
|
||||
});
|
||||
|
||||
it('should support new-style refs with mixed-up owners', () => {
|
||||
class Wrapper extends React.Component {
|
||||
getTitle = () => {
|
||||
return this.props.title;
|
||||
};
|
||||
|
||||
render() {
|
||||
return this.props.getContent();
|
||||
}
|
||||
}
|
||||
|
||||
let mounted = false;
|
||||
|
||||
class Component extends React.Component {
|
||||
getInner = () => {
|
||||
// (With old-style refs, it's impossible to get a ref to this div
|
||||
// because Wrapper is the current owner when this function is called.)
|
||||
return <div className="inner" ref={c => (this.innerRef = c)} />;
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Wrapper
|
||||
title="wrapper"
|
||||
ref={c => (this.wrapperRef = c)}
|
||||
getContent={this.getInner}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// Check .props.title to make sure we got the right elements back
|
||||
expect(this.wrapperRef.getTitle()).toBe('wrapper');
|
||||
expect(this.innerRef.className).toBe('inner');
|
||||
mounted = true;
|
||||
}
|
||||
}
|
||||
|
||||
ReactTestUtils.renderIntoDocument(<Component />);
|
||||
expect(mounted).toBe(true);
|
||||
});
|
||||
|
||||
it('should warn when `key` is being accessed on composite element', () => {
|
||||
const container = document.createElement('div');
|
||||
class Child extends React.Component {
|
||||
render() {
|
||||
return <div> {this.props.key} </div>;
|
||||
}
|
||||
}
|
||||
class Parent extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Child key="0" />
|
||||
<Child key="1" />
|
||||
<Child key="2" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
expect(() => ReactDOM.render(<Parent />, container)).toErrorDev(
|
||||
'Child: `key` is not a prop. Trying to access it will result ' +
|
||||
'in `undefined` being returned. If you need to access the same ' +
|
||||
'value within the child component, you should pass it as a different ' +
|
||||
'prop. (https://reactjs.org/link/special-props)'
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn when `ref` is being accessed', () => {
|
||||
const container = document.createElement('div');
|
||||
class Child extends React.Component {
|
||||
render() {
|
||||
return <div> {this.props.ref} </div>;
|
||||
}
|
||||
}
|
||||
class Parent extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Child ref="childElement" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
expect(() => ReactDOM.render(<Parent />, container)).toErrorDev(
|
||||
'Child: `ref` is not a prop. Trying to access it will result ' +
|
||||
'in `undefined` being returned. If you need to access the same ' +
|
||||
'value within the child component, you should pass it as a different ' +
|
||||
'prop. (https://reactjs.org/link/special-props)'
|
||||
);
|
||||
});
|
||||
|
||||
it('should warn when owner and self are different for string refs', () => {
|
||||
class ClassWithRenderProp extends React.Component {
|
||||
render() {
|
||||
return this.props.children();
|
||||
}
|
||||
}
|
||||
|
||||
class ClassParent extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<ClassWithRenderProp>{() => <div ref="myRef" />}</ClassWithRenderProp>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const container = document.createElement('div');
|
||||
if (process.env.BABEL_ENV === 'development') {
|
||||
expect(() => ReactDOM.render(<ClassParent />, container)).toErrorDev([
|
||||
'Warning: Component "ClassWithRenderProp" contains the string ref "myRef". ' +
|
||||
'Support for string refs will be removed in a future major release. ' +
|
||||
'This case cannot be automatically converted to an arrow function. ' +
|
||||
'We ask you to manually fix this case by using useRef() or createRef() instead. ' +
|
||||
'Learn more about using refs safely here: ' +
|
||||
'https://reactjs.org/link/strict-mode-string-ref',
|
||||
]);
|
||||
} else {
|
||||
ReactDOM.render(<ClassParent />, container);
|
||||
}
|
||||
});
|
||||
59
fixtures/legacy-jsx-runtimes/react-17/yarn.lock
Normal file
59
fixtures/legacy-jsx-runtimes/react-17/yarn.lock
Normal file
@@ -0,0 +1,59 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||
dependencies:
|
||||
js-tokens "^3.0.0 || ^4.0.0"
|
||||
|
||||
object-assign@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
|
||||
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
|
||||
|
||||
prop-types@^15.7.2:
|
||||
version "15.7.2"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||
dependencies:
|
||||
loose-envify "^1.4.0"
|
||||
object-assign "^4.1.1"
|
||||
react-is "^16.8.1"
|
||||
|
||||
react-dom@17.0.0-rc.3:
|
||||
version "17.0.0-rc.3"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.0-rc.3.tgz#6254f82c62ed569a2a90dcf1c7b71d4d8d951744"
|
||||
integrity sha512-rrmZ91kdXBaCVomiNUQ1WvEClb5GcmxewGurd3FnsXKJBOhFdlkGbT5MY5ZQkMXH5xnIvs5ZEEB2iBr2ZqKiqg==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
scheduler "0.20.0-rc.3"
|
||||
|
||||
react-is@^16.8.1:
|
||||
version "16.13.1"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||
|
||||
react@17.0.0-rc.3:
|
||||
version "17.0.0-rc.3"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-17.0.0-rc.3.tgz#ccb426b0146a8c10ee92c2a72d9d813a16a55806"
|
||||
integrity sha512-b1vEcXBmlN2Bu+k57jq2ytEo5p28g5fdRfc02JRdnvGZKKphvlUnAfsrUHiOmUtL/6wvFIusi2zxp8t60fihfw==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
scheduler@0.20.0-rc.3:
|
||||
version "0.20.0-rc.3"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.0-rc.3.tgz#ce616ebdd4073f5026718960d7e2d0928788c626"
|
||||
integrity sha512-rPwhSgPKhRqximLHdl+oJ/8HVcMS2vyZlH74OQHqKbH04ONgKNkJ13DZLPdFSYFos8FUj6+PduO9+OoRaG6QWQ==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
308
fixtures/legacy-jsx-runtimes/setupTests.js
Normal file
308
fixtures/legacy-jsx-runtimes/setupTests.js
Normal file
@@ -0,0 +1,308 @@
|
||||
'use strict';
|
||||
|
||||
// This is mostly copypasta from toWarnDev.js matchers
|
||||
// that we use in the main repo Jest configuration.
|
||||
|
||||
const expect = global.expect;
|
||||
|
||||
const jestDiff = require('jest-diff').default;
|
||||
const util = require('util');
|
||||
|
||||
function shouldIgnoreConsoleError(format, args) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
if (typeof format === 'string') {
|
||||
if (format.indexOf('Error: Uncaught [') === 0) {
|
||||
// This looks like an uncaught error from invokeGuardedCallback() wrapper
|
||||
// in development that is reported by jsdom. Ignore because it's noisy.
|
||||
return true;
|
||||
}
|
||||
if (format.indexOf('The above error occurred') === 0) {
|
||||
// This looks like an error addendum from ReactFiberErrorLogger.
|
||||
// Ignore it too.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (
|
||||
format != null &&
|
||||
typeof format.message === 'string' &&
|
||||
typeof format.stack === 'string' &&
|
||||
args.length === 0
|
||||
) {
|
||||
// In production, ReactFiberErrorLogger logs error objects directly.
|
||||
// They are noisy too so we'll try to ignore them.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// Looks legit
|
||||
return false;
|
||||
}
|
||||
|
||||
function normalizeCodeLocInfo(str) {
|
||||
if (typeof str !== 'string') {
|
||||
return str;
|
||||
}
|
||||
// This special case exists only for the special source location in
|
||||
// ReactElementValidator. That will go away if we remove source locations.
|
||||
str = str.replace(/Check your code at .+?:\d+/g, 'Check your code at **');
|
||||
// V8 format:
|
||||
// at Component (/path/filename.js:123:45)
|
||||
// React format:
|
||||
// in Component (at filename.js:123)
|
||||
return str.replace(/\n +(?:at|in) ([\S]+)[^\n]*/g, function(m, name) {
|
||||
return '\n in ' + name + ' (at **)';
|
||||
});
|
||||
}
|
||||
|
||||
const createMatcherFor = (consoleMethod, matcherName) =>
|
||||
function matcher(callback, expectedMessages, options = {}) {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
// Warn about incorrect usage of matcher.
|
||||
if (typeof expectedMessages === 'string') {
|
||||
expectedMessages = [expectedMessages];
|
||||
} else if (!Array.isArray(expectedMessages)) {
|
||||
throw Error(
|
||||
`${matcherName}() requires a parameter of type string or an array of strings ` +
|
||||
`but was given ${typeof expectedMessages}.`
|
||||
);
|
||||
}
|
||||
if (
|
||||
options != null &&
|
||||
(typeof options !== 'object' || Array.isArray(options))
|
||||
) {
|
||||
throw new Error(
|
||||
`${matcherName}() second argument, when present, should be an object. ` +
|
||||
'Did you forget to wrap the messages into an array?'
|
||||
);
|
||||
}
|
||||
if (arguments.length > 3) {
|
||||
// `matcher` comes from Jest, so it's more than 2 in practice
|
||||
throw new Error(
|
||||
`${matcherName}() received more than two arguments. ` +
|
||||
'Did you forget to wrap the messages into an array?'
|
||||
);
|
||||
}
|
||||
|
||||
const withoutStack = options.withoutStack;
|
||||
const logAllErrors = options.logAllErrors;
|
||||
const warningsWithoutComponentStack = [];
|
||||
const warningsWithComponentStack = [];
|
||||
const unexpectedWarnings = [];
|
||||
|
||||
let lastWarningWithMismatchingFormat = null;
|
||||
let lastWarningWithExtraComponentStack = null;
|
||||
|
||||
// Catch errors thrown by the callback,
|
||||
// But only rethrow them if all test expectations have been satisfied.
|
||||
// Otherwise an Error in the callback can mask a failed expectation,
|
||||
// and result in a test that passes when it shouldn't.
|
||||
let caughtError;
|
||||
|
||||
const isLikelyAComponentStack = message =>
|
||||
typeof message === 'string' &&
|
||||
(message.includes('\n in ') || message.includes('\n at '));
|
||||
|
||||
const consoleSpy = (format, ...args) => {
|
||||
// Ignore uncaught errors reported by jsdom
|
||||
// and React addendums because they're too noisy.
|
||||
if (
|
||||
!logAllErrors &&
|
||||
consoleMethod === 'error' &&
|
||||
shouldIgnoreConsoleError(format, args)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
const message = util.format(format, ...args);
|
||||
const normalizedMessage = normalizeCodeLocInfo(message);
|
||||
|
||||
// Remember if the number of %s interpolations
|
||||
// doesn't match the number of arguments.
|
||||
// We'll fail the test if it happens.
|
||||
let argIndex = 0;
|
||||
format.replace(/%s/g, () => argIndex++);
|
||||
if (argIndex !== args.length) {
|
||||
lastWarningWithMismatchingFormat = {
|
||||
format,
|
||||
args,
|
||||
expectedArgCount: argIndex,
|
||||
};
|
||||
}
|
||||
|
||||
// Protect against accidentally passing a component stack
|
||||
// to warning() which already injects the component stack.
|
||||
if (
|
||||
args.length >= 2 &&
|
||||
isLikelyAComponentStack(args[args.length - 1]) &&
|
||||
isLikelyAComponentStack(args[args.length - 2])
|
||||
) {
|
||||
lastWarningWithExtraComponentStack = {
|
||||
format,
|
||||
};
|
||||
}
|
||||
|
||||
for (let index = 0; index < expectedMessages.length; index++) {
|
||||
const expectedMessage = expectedMessages[index];
|
||||
if (
|
||||
normalizedMessage === expectedMessage ||
|
||||
normalizedMessage.includes(expectedMessage)
|
||||
) {
|
||||
if (isLikelyAComponentStack(normalizedMessage)) {
|
||||
warningsWithComponentStack.push(normalizedMessage);
|
||||
} else {
|
||||
warningsWithoutComponentStack.push(normalizedMessage);
|
||||
}
|
||||
expectedMessages.splice(index, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let errorMessage;
|
||||
if (expectedMessages.length === 0) {
|
||||
errorMessage =
|
||||
'Unexpected warning recorded: ' +
|
||||
this.utils.printReceived(normalizedMessage);
|
||||
} else if (expectedMessages.length === 1) {
|
||||
errorMessage =
|
||||
'Unexpected warning recorded: ' +
|
||||
jestDiff(expectedMessages[0], normalizedMessage);
|
||||
} else {
|
||||
errorMessage =
|
||||
'Unexpected warning recorded: ' +
|
||||
jestDiff(expectedMessages, [normalizedMessage]);
|
||||
}
|
||||
|
||||
// Record the call stack for unexpected warnings.
|
||||
// We don't throw an Error here though,
|
||||
// Because it might be suppressed by ReactFiberScheduler.
|
||||
unexpectedWarnings.push(new Error(errorMessage));
|
||||
};
|
||||
|
||||
// TODO Decide whether we need to support nested toWarn* expectations.
|
||||
// If we don't need it, add a check here to see if this is already our spy,
|
||||
// And throw an error.
|
||||
const originalMethod = console[consoleMethod];
|
||||
|
||||
// Avoid using Jest's built-in spy since it can't be removed.
|
||||
console[consoleMethod] = consoleSpy;
|
||||
|
||||
try {
|
||||
callback();
|
||||
} catch (error) {
|
||||
caughtError = error;
|
||||
} finally {
|
||||
// Restore the unspied method so that unexpected errors fail tests.
|
||||
console[consoleMethod] = originalMethod;
|
||||
|
||||
// Any unexpected Errors thrown by the callback should fail the test.
|
||||
// This should take precedence since unexpected errors could block warnings.
|
||||
if (caughtError) {
|
||||
throw caughtError;
|
||||
}
|
||||
|
||||
// Any unexpected warnings should be treated as a failure.
|
||||
if (unexpectedWarnings.length > 0) {
|
||||
return {
|
||||
message: () => unexpectedWarnings[0].stack,
|
||||
pass: false,
|
||||
};
|
||||
}
|
||||
|
||||
// Any remaining messages indicate a failed expectations.
|
||||
if (expectedMessages.length > 0) {
|
||||
return {
|
||||
message: () =>
|
||||
`Expected warning was not recorded:\n ${this.utils.printReceived(
|
||||
expectedMessages[0]
|
||||
)}`,
|
||||
pass: false,
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof withoutStack === 'number') {
|
||||
// We're expecting a particular number of warnings without stacks.
|
||||
if (withoutStack !== warningsWithoutComponentStack.length) {
|
||||
return {
|
||||
message: () =>
|
||||
`Expected ${withoutStack} warnings without a component stack but received ${warningsWithoutComponentStack.length}:\n` +
|
||||
warningsWithoutComponentStack.map(warning =>
|
||||
this.utils.printReceived(warning)
|
||||
),
|
||||
pass: false,
|
||||
};
|
||||
}
|
||||
} else if (withoutStack === true) {
|
||||
// We're expecting that all warnings won't have the stack.
|
||||
// If some warnings have it, it's an error.
|
||||
if (warningsWithComponentStack.length > 0) {
|
||||
return {
|
||||
message: () =>
|
||||
`Received warning unexpectedly includes a component stack:\n ${this.utils.printReceived(
|
||||
warningsWithComponentStack[0]
|
||||
)}\nIf this warning intentionally includes the component stack, remove ` +
|
||||
`{withoutStack: true} from the ${matcherName}() call. If you have a mix of ` +
|
||||
`warnings with and without stack in one ${matcherName}() call, pass ` +
|
||||
`{withoutStack: N} where N is the number of warnings without stacks.`,
|
||||
pass: false,
|
||||
};
|
||||
}
|
||||
} else if (withoutStack === false || withoutStack === undefined) {
|
||||
// We're expecting that all warnings *do* have the stack (default).
|
||||
// If some warnings don't have it, it's an error.
|
||||
if (warningsWithoutComponentStack.length > 0) {
|
||||
return {
|
||||
message: () =>
|
||||
`Received warning unexpectedly does not include a component stack:\n ${this.utils.printReceived(
|
||||
warningsWithoutComponentStack[0]
|
||||
)}\nIf this warning intentionally omits the component stack, add ` +
|
||||
`{withoutStack: true} to the ${matcherName} call.`,
|
||||
pass: false,
|
||||
};
|
||||
}
|
||||
} else {
|
||||
throw Error(
|
||||
`The second argument for ${matcherName}(), when specified, must be an object. It may have a ` +
|
||||
`property called "withoutStack" whose value may be undefined, boolean, or a number. ` +
|
||||
`Instead received ${typeof withoutStack}.`
|
||||
);
|
||||
}
|
||||
|
||||
if (lastWarningWithMismatchingFormat !== null) {
|
||||
return {
|
||||
message: () =>
|
||||
`Received ${
|
||||
lastWarningWithMismatchingFormat.args.length
|
||||
} arguments for a message with ${
|
||||
lastWarningWithMismatchingFormat.expectedArgCount
|
||||
} placeholders:\n ${this.utils.printReceived(
|
||||
lastWarningWithMismatchingFormat.format
|
||||
)}`,
|
||||
pass: false,
|
||||
};
|
||||
}
|
||||
|
||||
if (lastWarningWithExtraComponentStack !== null) {
|
||||
return {
|
||||
message: () =>
|
||||
`Received more than one component stack for a warning:\n ${this.utils.printReceived(
|
||||
lastWarningWithExtraComponentStack.format
|
||||
)}\nDid you accidentally pass a stack to warning() as the last argument? ` +
|
||||
`Don't forget warning() already injects the component stack automatically.`,
|
||||
pass: false,
|
||||
};
|
||||
}
|
||||
|
||||
return {pass: true};
|
||||
}
|
||||
} else {
|
||||
// Any uncaught errors or warnings should fail tests in production mode.
|
||||
callback();
|
||||
|
||||
return {pass: true};
|
||||
}
|
||||
};
|
||||
|
||||
expect.extend({
|
||||
toWarnDev: createMatcherFor('warn', 'toWarnDev'),
|
||||
toErrorDev: createMatcherFor('error', 'toErrorDev'),
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user