Skip to content

Commit 1806a16

Browse files
committed
feat: add tests and regex
1 parent d40abbe commit 1806a16

File tree

2 files changed

+128
-1
lines changed

2 files changed

+128
-1
lines changed
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
import { describe, expect, test } from 'vitest'
2+
import { defaultCodeFilter } from './reactCompilerPreset'
3+
4+
describe('defaultCodeFilter', () => {
5+
const cases: Record<string, [code: string, expected: boolean]> = {
6+
directive: ['"use memo";', true],
7+
8+
'component declaration': ['function App() { return <></> }', true],
9+
'component arrow expression': [
10+
'const MyComponent = () => { return <></> }',
11+
true,
12+
],
13+
'component arrow expressions': [
14+
'const a = 0, MyComponent = () => { return <></> }',
15+
true,
16+
],
17+
'component arrow expressions (let)': [
18+
'let a = 0, MyComponent = () => { return <></> }',
19+
true,
20+
],
21+
'component function expression': [
22+
'const MyComponent = function() { return <></> }',
23+
true,
24+
],
25+
'component function expression (let)': [
26+
'let MyComponent = function() { return <></> }',
27+
true,
28+
],
29+
'component function expression (var)': [
30+
'var MyComponent = function() { return <></> }',
31+
true,
32+
],
33+
'exported component declaration': [
34+
'export default function Page() { return <></> }',
35+
true,
36+
],
37+
'component assignment': [
38+
'let MyComponent; MyComponent = function() { return <></> }',
39+
true,
40+
],
41+
'component default declaration': [
42+
'const { MyComponent = function() { return <></> } } = {}',
43+
true,
44+
],
45+
'component default assignment': [
46+
'let MyComponent; ({ MyComponent = function() { return <></> } }) = {}',
47+
true,
48+
],
49+
'component property': [
50+
'const components = { MyComponent: () => <></> }',
51+
true,
52+
],
53+
'component method': [
54+
'const components = { MyComponent() { return <></> } }',
55+
true,
56+
],
57+
58+
'hook declaration': ['function useEffect() { return <></> }', true],
59+
'hook arrow expression': ['const useMyHook = () => { return <></> }', true],
60+
'hook function expression': [
61+
'const useMyHook = function() { return <></> }',
62+
true,
63+
],
64+
'hook with digit': ['function use0() { return <></> }', true],
65+
'hook using hooks': [
66+
'function useMyHook() { return useOtherHook() }',
67+
true,
68+
],
69+
'hook using nested hooks': [
70+
'function useMyHook() { return Foo.useOtherHook() }',
71+
true,
72+
],
73+
74+
'React.forwardRef': ['React.forwardRef(() => <></>)', true],
75+
'React.memo': ['React.memo(() => <></>)', true],
76+
forwardRef: [
77+
'import { forwardRef } from "react"; forwardRef(() => <></>)',
78+
true,
79+
],
80+
memo: ['import { memo } from "react"; memo(() => <></>)', true],
81+
82+
'edge case: memo callback with hooks': [
83+
`import React, { useState } from "react";
84+
import { jsx } from "react/jsx-runtime"
85+
86+
export const components = {
87+
A: React.memo(() => {
88+
const [state, setState] = useState(0);
89+
90+
return jsx("div", { children: state })
91+
})
92+
}`,
93+
true,
94+
],
95+
'edge case: memo without namespace': [
96+
`import { memo, useState } from "react";
97+
98+
export default memo(() => {
99+
const [count, setCount] = useState(0);
100+
return <div>{count}</div>
101+
})`,
102+
true,
103+
],
104+
'edge case: memo without namespace from re-export': [
105+
`import { memo, useState } from "my-react";
106+
107+
export default memo(() => {
108+
const [count, setCount] = useState(0);
109+
return <div>{count}</div>
110+
})`,
111+
true,
112+
],
113+
114+
'simple variable': ['const foo = 1', false],
115+
'lowercase function': ['function bar() {}', false],
116+
'lowercase arrow function': ['let baz = () => {}', false],
117+
}
118+
119+
for (const [name, [code, expected]] of Object.entries(cases)) {
120+
test(name, () => {
121+
expect(defaultCodeFilter.test(code)).toBe(expected)
122+
})
123+
}
124+
})

packages/plugin-react/src/reactCompilerPreset.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import type {
33
RolldownBabelPreset,
44
} from '#optionalTypes'
55

6+
export const defaultCodeFilter =
7+
/forwardRef|memo|function\s+(?:[A-Z]|use[A-Z0-9])|(?:[A-Z]|use[A-Z0-9])\S*\s*[:=(]/
8+
69
export const reactCompilerPreset = (
710
options: Pick<
811
ReactCompilerBabelPluginOptions,
@@ -18,7 +21,7 @@ export const reactCompilerPreset = (
1821
code:
1922
options.compilationMode === 'annotation'
2023
? /['"]use memo['"]/
21-
: /\b[A-Z]|\buse[A-Z0-9]/,
24+
: defaultCodeFilter,
2225
},
2326
applyToEnvironmentHook: (env) => env.config.consumer === 'client',
2427
optimizeDeps: {

0 commit comments

Comments
 (0)