Omlet vs. React Scanner
Before Omlet was around, the most common way developers would analyze component usage was to use React Scanner. Let's look at how is Omlet different.
In React Scanner, components with zero usages are not detected. Components used out of JSX expressions are also not detected. For example, the usage of IconTick in this component is not detected by react-scanner.
import IconTick from "../IconTick";
class Icons extends Component {
icons = {
...
IconTick,
};
render() {
const { searchValue } = this.state;
return (
<div class="iconSearch">
<div class="icons">
{Object.entries(this.icons)
.filter(([iconKey]) =>
iconKey.toLowerCase().includes(searchValue)
)
.map(([iconKey, Icon]) => (
...
))}
</div>
</div>
);
}
}
Dependencies among components defined in the same module are not detected
Dependency between
NamedComponentWrapped
and ComponentUsingNamedWrappedComponent
is missing in react-scanner results.export function ComponentUsingNamedWrappedComponent() {
return <NamedComponentWrapped/>;
}
export function NamedComponentWrapped() {
return <div></div>;
}
Usages are reported at the file-level, so dependencies of components defined in the same module are not visible.
For example using the below code as an example…react-scanner’s usage detection result is:
- Button in components/navigation.jsx
- Input in components/navigation.jsx
whereas Omlet reports the following:
- Footer uses Button
- Header uses Input
// file: components/navigation.jsx
import { Button, Input } from "./components";
export function Footer() {
return <div>
<Button/>
</div>;
}
export function Header() {
return <div>
<h1>Hello</h1>
<Input/>
</div>;
}
react-scanner does not follow exports to find the source component for imports.
Instead, it detects names imported from modules. This causes duplicate components and incorrect usage numbers. For example if we use the below example…This results in 4 separate button components in react-scanner data since each of them has distinct import name and import path combinations:
- Button from components/Button
- Button from components/Button/Button
- SameButton from components/Button
- TheButton from components/Button
In react-scanners report, each combination has their separate usage counts where Omlet detects that they’re actually the same component and gives the total (correct) number of usages.
// file: components/Button/Button.jsx
export function Button() { .. }
// file: components/Button/index.jsx
import { Button } from "./Button";
export { Button };
export default Button;
// file app/pageA.jsx
import { Button } from "../components/Button";
// file app/pageB.jsx
import { Button } from "../components/Button/Button";
// file app/pageC.jsx
import SameButton from "../components/Button";
// file app/pageC.jsx
import TheButton from "../components/Button";
Aliased imports appear as separate components in react-scanner reports. Similar to the case mentioned under the Import resolution section, this causes fragmented usage counts and duplicate entries.
// file: frontend/src/layout/navigation/TopBar/SitePopover.tsx
import { ProfilePicture } from 'lib/lemon-ui/ProfilePicture'
// file: frontend/src/lib/lemon-ui/LemonTable/columnUtils.tsx
import { ProfilePicture } from '../ProfilePicture'
- HTML tags in JSX are not detected: Omlet doesn’t detect React element equivalent of HTML tags such as div, img, etc.
- Prop usage tracking: this will be available in early-mid September
- Instance counts: Omlet doesn’t count component instances. Instead, it reports unique parent components for each component. react-scanner reports each instance separately.
Last modified 1d ago