npm package: @squadbase/swc-plugin-component-annotate
Description: Use SWC to automatically annotate React components with data attributes for component tracking
Author: kt83
Latest version: 1.11.1

# SWC Plugin: Component Annotate [![npm badge](https://img.shields.io/npm/v/@squadbase/swc-plugin-component-annotate)](https://www.npmjs.com/package/@squadbase/swc-plugin-component-annotate)

> **Note**: This is a fork of [swc-plugin-component-annotate](https://github.com/scttcper/swc-plugin-component-annotate) by [scttcper](https://github.com/scttcper), maintained by squadbase for internal use and community contributions.

A SWC plugin that automatically annotates React components with data attributes for component tracking and debugging.

## Overview

This plugin transforms React components by adding data attributes that help with tracking and debugging. It automatically identifies React components (function components, arrow function components, and class components) and adds the following attributes:

- `data-component`: The component name (added to root elements)
- `data-element`: The element/component name (added to non-HTML elements)
- `data-source-file`: The source filename
- `data-source-path`: The absolute file path (opt-in)
- `data-filepath`: The relative file path from project root (opt-in)

## Features

- ✅ **Function Components**: `function MyComponent() { ... }`
- ✅ **Arrow Function Components**: `const MyComponent = () => { ... }`
- ✅ **Class Components**: `class MyComponent extends Component { ... }`
- ✅ **React Fragments**: Supports `Fragment`, `React.Fragment`, and `<>` syntax
- ✅ **Nested Components**: Properly handles component hierarchies
- ✅ **React Native Support**: Uses camelCase attributes when configured
- ✅ **Configurable**: Ignore specific components, annotate fragments, etc.

## Installation

```bash
npm install --save-dev @squadbase/swc-plugin-component-annotate
```

## Usage

### Basic Configuration

Add the plugin to your `.swcrc` configuration:

```json
{
  "jsc": {
    "experimental": {
      "plugins": [
        ["@squadbase/swc-plugin-component-annotate", {}]
      ]
    }
  }
}
```

### Configuration Options

```json
{
  "jsc": {
    "experimental": {
      "plugins": [
        ["@squadbase/swc-plugin-component-annotate", {
          "native": false,
          "ignored-components": ["MyIgnoredComponent"],
          "component-attr": "data-component",
          "element-attr": "data-element",
          "source-file-attr": "data-source-file",
          "source-path-attr": "data-source-path",
          "filepath-attr": "data-filepath"
        }]
      ]
    }
  }
}
```

#### Options

- **`native`** (boolean, default: `false`): Use React Native attribute names (camelCase)
  - `false`: `data-component`, `data-element`, `data-source-file`
  - `true`: `dataComponent`, `dataElement`, `dataSourceFile`

- **`ignored-components`** (array, default: `[]`): List of component names to skip during annotation

- **`component-attr`** (string, optional): Custom component attribute name (overrides default and native setting)

- **`element-attr`** (string, optional): Custom element attribute name (overrides default and native setting)

- **`source-file-attr`** (string, optional): Custom source file attribute name (overrides default and native setting)

- **`source-path-attr`** (string, optional): Enable and customize the absolute path attribute. When set, adds the full filesystem path to components (e.g., `/absolute/path/to/src/components/Button.tsx`)

- **`filepath-attr`** (string, optional): Enable and customize the relative path attribute. When set, adds the relative path from project root to components (e.g., `src/components/Button.tsx`). The project root is detected by searching for `.git` directory or `package.json`

### File Path Tracking

To include file path information in your components, you can use either `source-path-attr` (absolute path) or `filepath-attr` (relative path from project root):

```json
{
  "jsc": {
    "experimental": {
      "plugins": [
        ["@squadbase/swc-plugin-component-annotate", {
          "filepath-attr": "data-filepath"
        }]
      ]
    }
  }
}
```

This will generate attributes like:
```jsx
<div
  data-component="MyComponent"
  data-source-file="MyComponent.jsx"
  data-filepath="src/components/MyComponent.jsx">
  <CustomButton
    data-element="CustomButton"
    data-source-file="MyComponent.jsx"
    data-filepath="src/components/MyComponent.jsx">
    Click me
  </CustomButton>
</div>
```

### Sentry Integration

To use Sentry-specific attribute names for compatibility with Sentry's tracking:

```json
{
  "jsc": {
    "experimental": {
      "plugins": [
        ["@squadbase/swc-plugin-component-annotate", {
          "component-attr": "data-sentry-component",
          "element-attr": "data-sentry-element",
          "source-file-attr": "data-sentry-source-file"
        }]
      ]
    }
  }
}
```

This will generate attributes like:
```jsx
<div data-sentry-component="MyComponent" data-sentry-source-file="MyComponent.jsx">
  <CustomButton data-sentry-element="CustomButton" data-sentry-source-file="MyComponent.jsx">
    Click me
  </CustomButton>
</div>
```

## Examples

### Input

```jsx
import React from 'react';

const MyComponent = () => {
  return (
    <div>
      <h1>Hello World</h1>
      <button>Click me</button>
    </div>
  );
};

export default MyComponent;
```

### Output

```jsx
import React from 'react';

const MyComponent = () => {
  return (
    <div data-component="MyComponent" data-source-file="MyComponent.jsx">
      <h1>Hello World</h1>
      <button>Click me</button>
    </div>
  );
};

export default MyComponent;
```

### Class Component Example

```jsx
// Input
class MyClassComponent extends Component {
  render() {
    return <div><h1>Hello from class</h1></div>;
  }
}

// Output
class MyClassComponent extends Component {
  render() {
    return <div data-component="MyClassComponent" data-source-file="MyComponent.jsx">
      <h1>Hello from class</h1>
    </div>;
  }
}
```

### React Native Example

With `"native": true`:

```jsx
// Output
const MyComponent = () => {
  return (
    <View dataComponent="MyComponent" dataSourceFile="MyComponent.jsx">
      <Text>Hello World</Text>
    </View>
  );
};
```

## Related

- [Sentry Babel Component Annotate Plugin](https://github.com/getsentry/sentry-javascript-bundler-plugins/tree/main/packages/babel-plugin-component-annotate)