Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f940f4b

Browse files
author
Wang Yilin
committedOct 26, 2021
[React Refresh] support typescript namespace syntax
1 parent 4298ddb commit f940f4b

File tree

5 files changed

+80
-14
lines changed

5 files changed

+80
-14
lines changed
 

‎package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
1717
"@babel/plugin-syntax-import-meta": "^7.10.4",
1818
"@babel/plugin-syntax-jsx": "^7.10.4",
19+
"@babel/plugin-syntax-typescript": "^7.14.5",
1920
"@babel/plugin-transform-arrow-functions": "^7.10.4",
2021
"@babel/plugin-transform-async-to-generator": "^7.10.4",
2122
"@babel/plugin-transform-block-scoped-functions": "^7.10.4",
@@ -35,7 +36,6 @@
3536
"@babel/preset-flow": "^7.10.4",
3637
"@babel/preset-react": "^7.10.4",
3738
"@babel/traverse": "^7.11.0",
38-
"web-streams-polyfill": "^3.1.1",
3939
"abort-controller": "^3.0.0",
4040
"art": "0.10.1",
4141
"babel-eslint": "^10.0.3",
@@ -96,6 +96,7 @@
9696
"through2": "^3.0.1",
9797
"tmp": "^0.1.0",
9898
"typescript": "^3.7.5",
99+
"web-streams-polyfill": "^3.1.1",
99100
"webpack": "^4.41.2",
100101
"yargs": "^15.3.1"
101102
},

‎packages/react-refresh/src/ReactFreshBabelPlugin.js

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -478,6 +478,7 @@ export default function(babel, opts = {}) {
478478
const node = path.node;
479479
let programPath;
480480
let insertAfterPath;
481+
let modulePrefix = '';
481482
switch (path.parent.type) {
482483
case 'Program':
483484
insertAfterPath = path;
@@ -486,6 +487,13 @@ export default function(babel, opts = {}) {
486487
case 'ExportNamedDeclaration':
487488
insertAfterPath = path.parentPath;
488489
programPath = insertAfterPath.parentPath;
490+
while (programPath.type !== 'Program') {
491+
if (programPath.type === 'TSModuleDeclaration') {
492+
// ExportNamedDeclaration can be nested in TSModules in typescript
493+
modulePrefix = programPath.node.id.name + '$' + modulePrefix;
494+
}
495+
programPath = programPath.parentPath;
496+
}
489497
break;
490498
case 'ExportDefaultDeclaration':
491499
insertAfterPath = path.parentPath;
@@ -512,20 +520,17 @@ export default function(babel, opts = {}) {
512520
seenForRegistration.add(node);
513521
// Don't mutate the tree above this point.
514522

523+
const innerName = modulePrefix + inferredName;
515524
// export function Named() {}
516525
// function Named() {}
517-
findInnerComponents(
518-
inferredName,
519-
path,
520-
(persistentID, targetExpr) => {
521-
const handle = createRegistration(programPath, persistentID);
522-
insertAfterPath.insertAfter(
523-
t.expressionStatement(
524-
t.assignmentExpression('=', handle, targetExpr),
525-
),
526-
);
527-
},
528-
);
526+
findInnerComponents(innerName, path, (persistentID, targetExpr) => {
527+
const handle = createRegistration(programPath, persistentID);
528+
insertAfterPath.insertAfter(
529+
t.expressionStatement(
530+
t.assignmentExpression('=', handle, targetExpr),
531+
),
532+
);
533+
});
529534
},
530535
exit(path) {
531536
const node = path.node;
@@ -679,6 +684,7 @@ export default function(babel, opts = {}) {
679684
const node = path.node;
680685
let programPath;
681686
let insertAfterPath;
687+
let modulePrefix = '';
682688
switch (path.parent.type) {
683689
case 'Program':
684690
insertAfterPath = path;
@@ -687,6 +693,13 @@ export default function(babel, opts = {}) {
687693
case 'ExportNamedDeclaration':
688694
insertAfterPath = path.parentPath;
689695
programPath = insertAfterPath.parentPath;
696+
while (programPath.type !== 'Program') {
697+
if (programPath.type === 'TSModuleDeclaration') {
698+
// ExportNamedDeclaration can be nested in TSModules in typescript
699+
modulePrefix = programPath.node.id.name + '$' + modulePrefix;
700+
}
701+
programPath = programPath.parentPath;
702+
}
690703
break;
691704
case 'ExportDefaultDeclaration':
692705
insertAfterPath = path.parentPath;
@@ -710,8 +723,9 @@ export default function(babel, opts = {}) {
710723
}
711724
const declPath = declPaths[0];
712725
const inferredName = declPath.node.id.name;
726+
const innerName = modulePrefix + inferredName;
713727
findInnerComponents(
714-
inferredName,
728+
innerName,
715729
declPath,
716730
(persistentID, targetExpr, targetPath) => {
717731
if (targetPath === null) {

‎packages/react-refresh/src/__tests__/ReactFreshBabelPlugin-test.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,4 +536,22 @@ describe('ReactFreshBabelPlugin', () => {
536536
`),
537537
).toMatchSnapshot();
538538
});
539+
540+
it('supports typescript namespace syntax', () => {
541+
expect(
542+
transform(
543+
`
544+
namespace Foo {
545+
export namespace Bar {
546+
export const A = () => {};
547+
export function B() {};
548+
}
549+
550+
export const C = () => {};
551+
}
552+
`,
553+
{plugins: [['@babel/plugin-syntax-typescript', {isTSX: true}]]},
554+
),
555+
).toMatchSnapshot();
556+
});
539557
});

‎packages/react-refresh/src/__tests__/__snapshots__/ReactFreshBabelPlugin-test.js.snap

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,26 @@ $RefreshReg$(_c, "Hello");
618618
$RefreshReg$(_c2, "Bar");
619619
`;
620620

621+
exports[`ReactFreshBabelPlugin supports typescript namespace syntax 1`] = `
622+
namespace Foo {
623+
export namespace Bar {
624+
export const A = () => {};
625+
_c = A;
626+
export function B() {}
627+
_c2 = B;
628+
;
629+
}
630+
export const C = () => {};
631+
_c3 = C;
632+
}
633+
634+
var _c, _c2, _c3;
635+
636+
$RefreshReg$(_c, "Foo$Bar$A");
637+
$RefreshReg$(_c2, "Foo$Bar$B");
638+
$RefreshReg$(_c3, "Foo$C");
639+
`;
640+
621641
exports[`ReactFreshBabelPlugin uses custom identifiers for $RefreshReg$ and $RefreshSig$ 1`] = `
622642
var _s = import.meta.refreshSig();
623643

‎yarn.lock

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,11 @@
405405
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af"
406406
integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ==
407407

408+
"@babel/helper-plugin-utils@^7.14.5":
409+
version "7.14.5"
410+
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9"
411+
integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ==
412+
408413
"@babel/helper-regex@^7.10.4":
409414
version "7.10.5"
410415
resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.5.tgz#32dfbb79899073c415557053a19bd055aae50ae0"
@@ -847,6 +852,13 @@
847852
dependencies:
848853
"@babel/helper-plugin-utils" "^7.12.13"
849854

855+
"@babel/plugin-syntax-typescript@^7.14.5":
856+
version "7.14.5"
857+
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716"
858+
integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==
859+
dependencies:
860+
"@babel/helper-plugin-utils" "^7.14.5"
861+
850862
"@babel/plugin-transform-arrow-functions@^7.0.0":
851863
version "7.8.3"
852864
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz#82776c2ed0cd9e1a49956daeb896024c9473b8b6"
@@ -6442,6 +6454,7 @@ eslint-plugin-no-unsanitized@3.1.2:
64426454

64436455
"eslint-plugin-react-internal@link:./scripts/eslint-rules":
64446456
version "0.0.0"
6457+
uid ""
64456458

64466459
eslint-plugin-react@^6.7.1:
64476460
version "6.10.3"

0 commit comments

Comments
 (0)
Please sign in to comment.