
# headless-js-bundle-validator

The `headless-js-bundle-validator` tool helps developers:

1. List modules that are **not supported** in the headless JS context.
2. Trace the origin of those modules in their headless JS task or service bundles.

> ⚠️ **Note**: This is an early version of the tool and may contain bugs. Please report issues or feature requests via the Kepler Forum or through your Amazon contact.

---

## Requirements

- Your JS bundle must be built in **debug mode**.
- Hermes bytecode bundles **are not supported**.

---

## Installation

This tool is currently distributed as an npm tarball. Install it globally with:

```bash
npm install -g headless-js-bundle-validator-1.0.1.tgz
```

After installation, run:

```bash
headless-js-bundle-validator --help
```

---

## Usage

After building your app in debug mode, locate the headless JS task and service bundles (usually named `task.bundle` and `service.bundle`).

To list unsupported modules in your headless JS bundle:

```bash
headless-js-bundle-validator good.service.bundle --list-unsupported-modules
```

### Example Output (Working Bundle)

```bash
# headless-js-bundle-validator good.service.bundle --list-unsupported-modules
Running bundle validation...

No unsupported modules found.
```

### Example Output (Non-working Bundle)

```bash
# headless-js-bundle-validator bad.service.bundle --list-unsupported-modules
Running bundle validation...

Unsupported modules found:
- node_modules/@amzn/react-native-kepler/index.js
- node_modules/react/index.js
- node_modules/react/jsx-runtime.js
- node_modules/@amzn/react-native-kepler/Libraries/Image/AssetRegistry.js
- node_modules/@amzn/react-native-kepler/Libraries/Core/Devtools/parseErrorStack.js
- node_modules/@amzn/react-native-kepler/Libraries/Core/Devtools/symbolicateStackTrace.js
- node_modules/@amzn/react-native-kepler/Libraries/Core/Devtools/getDevServer.js
```

The tool prints the **first unsupported module** found in each branch and stops traversal beyond that point. This keeps the output concise. Removing an unsupported module will eliminate its transitive dependencies as well.

---

## Tracing Module Origins

Once you have the list of unsupported modules, you can trace the origin of each one.

For example, to find out what imports `@amzn/react-native-kepler/index.js`:

```bash
headless-js-bundle-validator bad.service.bundle --module-path node_modules/@amzn/react-native-kepler/index.js
```

> 🛠️ The tool uses Graphviz's `dot` CLI to generate `.png` graphs. Follow the tool’s instructions to install `graphviz` if needed.

---

## Graph Filters

To reduce graph complexity, you can use these filters:

```
--max-depth <number>                  Limit the depth of the dependency graph (must be > 0)
--only-app-modules                    Only include app modules (exclude node_modules)
--only-library-modules                Only include library modules (node_modules only)
--skip-react-native-kepler-modules    Exclude react-native-kepler modules from the graph
```

---

## Recommended Workflow

1. **Identify app modules that directly import the unsupported module**:

    ```bash
    headless-js-bundle-validator bad.service.bundle       --module-path node_modules/@amzn/react-native-kepler/index.js       --only-library-modules       --only-app-modules
    ```

2. **Identify third-party libraries bringing in the module transitively**:

    ```bash
    headless-js-bundle-validator bad.service.bundle       --module-path node_modules/@amzn/react-native-kepler/index.js       --only-library-modules       --skip-react-native-kepler-modules
    ```

    > If you're using a library that imports unsupported modules, you currently cannot use it in a headless JS context. Reach out to your Amazon contact for potential workarounds. We aim to expand the list of supported libraries over time.

3. **Zoom into the graph using `--max-depth`**:

    ```bash
    headless-js-bundle-validator bad.service.bundle       --module-path node_modules/@amzn/react-native-kepler/index.js       --max-depth 3
    ```

---

## Additional Use Cases

You can also trace the origin of **any module**, not just unsupported ones. This can be useful when you want to simplify the graph from the **left side** (starting modules), whereas `--max-depth` simplifies it from the **right side** (leaf modules).

> ❗ If you're doing this, avoid using `--skip-react-native-kepler-modules`, as it may omit relevant paths.
