Skip to content

Commit

Permalink
feat(babel): react hooks aren't needed for evaluation (#1031)
Browse files Browse the repository at this point in the history
  • Loading branch information
Anber committed Jul 31, 2022
1 parent 36ff6b2 commit 3c593aa
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 13 deletions.
5 changes: 5 additions & 0 deletions .changeset/real-terms-brush.md
@@ -0,0 +1,5 @@
---
'@linaria/babel-preset': patch
---

React hooks aren't needed for evaluation so we can replace them as we already do with react components (fixes compatability with [ariakit](https://github.com/ariakit/ariakit) and some other libraries).
32 changes: 19 additions & 13 deletions packages/babel/src/plugins/preeval.ts
Expand Up @@ -6,7 +6,7 @@ import type { BabelFile, NodePath, PluginObj } from '@babel/core';
import type { CallExpression, Identifier } from '@babel/types';

import { createCustomDebug } from '@linaria/logger';
import type { StrictOptions, IImport } from '@linaria/utils';
import type { StrictOptions, IImport, ISideEffectImport } from '@linaria/utils';
import {
collectExportsAndImports,
getFileIdx,
Expand Down Expand Up @@ -50,14 +50,25 @@ const isBrowserGlobal = (id: NodePath<Identifier>) => {
return forbiddenGlobals.has(id.node.name) && isGlobal(id);
};

function isCreateElement(
function isHookOrCreateElement(name: string): boolean {
return name === 'createElement' || /use[A-Z]/.test(name);
}

function isUnnecessaryReact(
p: NodePath<CallExpression>,
reactImports: IImport[]
imports: (IImport | ISideEffectImport)[]
): boolean {
const reactImports = imports.filter(
(i) =>
i.source === 'react' &&
(i.imported === 'default' ||
(i.imported && isHookOrCreateElement(i.imported)))
) as IImport[];

if (reactImports.length === 0) return false;
const callee = p.get('callee');
if (callee.isIdentifier({ name: 'createElement' })) {
const bindingPath = callee.scope.getBinding('createElement')?.path;
if (callee.isIdentifier() && isHookOrCreateElement(callee.node.name)) {
const bindingPath = callee.scope.getBinding(callee.node.name)?.path;
return reactImports.some((i) => bindingPath?.isAncestor(i.local));
}

Expand All @@ -73,7 +84,8 @@ function isCreateElement(
if (
!defaultImport ||
!defaultImport.local.isIdentifier() ||
!property.isIdentifier({ name: 'createElement' }) ||
!property.isIdentifier() ||
!isHookOrCreateElement(property.node.name) ||
!object.isIdentifier({ name: defaultImport.local.node.name })
) {
return false;
Expand Down Expand Up @@ -103,12 +115,6 @@ export default function preeval(
file.opts.filename
);

const reactImports = imports.filter(
(i) =>
i.source === 'react' &&
(i.imported === 'default' || i.imported === 'createElement')
) as IImport[];

const jsxRuntime = imports.find((i) => i.source === 'react/jsx-runtime');
const jsxRuntimeName =
jsxRuntime?.local?.isIdentifier() && jsxRuntime?.local?.node?.name;
Expand Down Expand Up @@ -137,7 +143,7 @@ export default function preeval(
}
}

if (isCreateElement(p, reactImports)) {
if (isUnnecessaryReact(p, imports)) {
JSXElementsRemover(p);
}
},
Expand Down

0 comments on commit 3c593aa

Please sign in to comment.