Skip to content

Commit c435eaa

Browse files
committed
fix: babel plugin should use only extrernals hooks, fixes #1285
1 parent 8bbc6d3 commit c435eaa

File tree

3 files changed

+2463
-77
lines changed

3 files changed

+2463
-77
lines changed

Diff for: src/fresh/babel.js

+6-77
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ export default function(babel) {
193193
}
194194
}
195195

196-
function getHookCallsSignature(functionNode) {
196+
function getHookCallsSignature(functionNode, scope) {
197197
const fnHookCalls = hookCalls.get(functionNode);
198198
if (fnHookCalls === undefined) {
199199
return null;
@@ -202,6 +202,7 @@ export default function(babel) {
202202
key: fnHookCalls.map(call => call.name + '{' + call.key + '}').join('\n'),
203203
customHooks: fnHookCalls
204204
.filter(call => !isBuiltinHook(call.name))
205+
.filter(call => scope.parent.hasBinding(call.name))
205206
.map(call => t.cloneDeep(call.callee)),
206207
};
207208
}
@@ -240,6 +241,7 @@ export default function(babel) {
240241
return;
241242
}
242243
const fnScope = path.scope.getFunctionParent();
244+
243245
if (fnScope === null) {
244246
return;
245247
}
@@ -249,6 +251,7 @@ export default function(babel) {
249251
if (!hookCalls.has(fnNode)) {
250252
hookCalls.set(fnNode, []);
251253
}
254+
252255
let hookCallsForFn = hookCalls.get(fnNode);
253256
let key = '';
254257
if (path.parent.type === 'VariableDeclarator') {
@@ -384,7 +387,7 @@ export default function(babel) {
384387
if (id === null) {
385388
return;
386389
}
387-
const signature = getHookCallsSignature(node);
390+
const signature = getHookCallsSignature(node, path.scope);
388391
if (signature === null) {
389392
return;
390393
}
@@ -424,7 +427,7 @@ export default function(babel) {
424427
'ArrowFunctionExpression|FunctionExpression': {
425428
exit(path) {
426429
const node = path.node;
427-
const signature = getHookCallsSignature(node);
430+
const signature = getHookCallsSignature(node, path.scope);
428431
if (signature === null) {
429432
return;
430433
}
@@ -474,80 +477,6 @@ export default function(babel) {
474477
}
475478
},
476479
},
477-
VariableDeclaration(path) {
478-
return;
479-
const node = path.node;
480-
let programPath;
481-
let insertAfterPath;
482-
switch (path.parent.type) {
483-
case 'Program':
484-
insertAfterPath = path;
485-
programPath = path.parentPath;
486-
break;
487-
case 'ExportNamedDeclaration':
488-
insertAfterPath = path.parentPath;
489-
programPath = insertAfterPath.parentPath;
490-
break;
491-
case 'ExportDefaultDeclaration':
492-
insertAfterPath = path.parentPath;
493-
programPath = insertAfterPath.parentPath;
494-
break;
495-
default:
496-
return;
497-
}
498-
499-
// Make sure we're not mutating the same tree twice.
500-
// This can happen if another Babel plugin replaces parents.
501-
if (seenForRegistration.has(node)) {
502-
return;
503-
}
504-
seenForRegistration.add(node);
505-
// Don't mutate the tree above this point.
506-
507-
const declPaths = path.get('declarations');
508-
if (declPaths.length !== 1) {
509-
return;
510-
}
511-
const declPath = declPaths[0];
512-
const inferredName = declPath.node.id.name;
513-
findInnerComponents(
514-
inferredName,
515-
declPath,
516-
(persistentID, targetExpr, targetPath) => {
517-
if (targetPath === null) {
518-
// For case like:
519-
// export const Something = hoc(Foo)
520-
// we don't want to wrap Foo inside the call.
521-
// Instead we assume it's registered at definition.
522-
return;
523-
}
524-
const handle = createRegistration(programPath, persistentID);
525-
if (
526-
(targetExpr.type === 'ArrowFunctionExpression' ||
527-
targetExpr.type === 'FunctionExpression') &&
528-
targetPath.parent.type === 'VariableDeclarator'
529-
) {
530-
// Special case when a function would get an inferred name:
531-
// let Foo = () => {}
532-
// let Foo = function() {}
533-
// We'll register it on next line so that
534-
// we don't mess up the inferred 'Foo' function name.
535-
insertAfterPath.insertAfter(
536-
t.expressionStatement(
537-
t.assignmentExpression('=', handle, declPath.node.id),
538-
),
539-
);
540-
// Result: let Foo = () => {}; _c1 = Foo;
541-
} else {
542-
// let Foo = hoc(() => {})
543-
targetPath.replaceWith(
544-
t.assignmentExpression('=', handle, targetExpr),
545-
);
546-
// Result: let Foo = _c1 = hoc(() => {})
547-
}
548-
},
549-
);
550-
},
551480
Program: {
552481
enter(path) {
553482
// This is a separate early visitor because we need to collect Hook calls

Diff for: test/__babel_fixtures__/hooks.js

+10
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ const useCustomHookAgain = () => {
4242
useExternalHook();
4343
};
4444

45+
const useInnerHook = ({useHookFromProps}) => {
46+
const useHookBase = () => useState();
47+
const useHook = () => useState(useHookFromProps(useHookBase()));
48+
useHookFromProps();
49+
{
50+
// sub scope
51+
useHook();
52+
}
53+
};
54+
4555
function useFunc () {
4656
useState(42);
4757
useEffectHook();

0 commit comments

Comments
 (0)