npm package: @oatfi/oatfi-loader
Description: Module Federation Loader for consuming components from Oatfi Components
Author: Oatfi
Latest version: 1.0.4

# Module Federation Loader

A simple loader package that wraps the module federation logic to consume components from Oatfi Components. **No module federation setup required in your consuming app!**

## Features

- **Zero Host Configuration**: Automatically detects and reuses React instances from host applications
- **Shared Dependency Management**: Handles React and React-DOM sharing without conflicts
- **Version Compatibility**: Checks and handles React version mismatches gracefully
- **Automatic Fallbacks**: Falls back to local React if host React is incompatible
- **Debugging Tools**: Built-in tools to inspect shared dependency status

## Installation

```bash
npm install oatfi-loader
# or
yarn add oatfi-loader
# or
pnpm add oatfi-loader
```

## Usage

### Basic Usage

```tsx
import React from 'react';
import { initialize, getContent } from 'oatfi-loader';

// Initialize the loader (call this once in your app)
initialize();

function App() {
  const Content = getContent();

  return (
    <div>
      <Content content="Hello from loader!" />
    </div>
  );
}
```

### With Custom Configuration

```tsx
import React from 'react';
import { initialize, getContent } from 'oatfi-loader';

// Initialize with custom configuration
initialize({
  oatfiComponentsUrl: 'http://localhost:3001',
  fallback: <div>Custom loading...</div>
});

function App() {
  const Content = getContent();

  return (
    <div>
      <Content content="Hello from loader!" />
    </div>
  );
}
```

### Using the Loader Instance Directly

```tsx
import React from 'react';
import { loader } from 'oatfi-loader';

// Initialize the loader
loader.initialize();

function App() {
  const Content = loader.getContent();

  return (
    <div>
      <Content content="Hello from loader!" />
    </div>
  );
}
```

### Creating a Custom Loader Instance

```tsx
import React from 'react';
import { ModuleFederationLoader } from 'oatfi-loader';

// Create a custom loader instance
const customLoader = new ModuleFederationLoader({
  oatfiComponentsUrl: 'https://my-oatfi-components.com',
  fallback: <div>Loading components...</div>
});

// Initialize
customLoader.initialize();

function App() {
  const Content = customLoader.getContent();

  return (
    <div>
      <Content content="Hello from custom loader!" />
    </div>
  );
}
```

### Debugging Shared Dependencies

```tsx
import React from 'react';
import { initialize, getContent, getSharedDependencyInfo } from 'oatfi-loader';

// Initialize the loader
initialize({
  oatfiComponentsUrl: 'http://localhost:3001'
});

function App() {
  const Content = getContent();
  
  // Log shared dependency information for debugging
  React.useEffect(() => {
    const dependencyInfo = getSharedDependencyInfo();
    console.log('Shared Dependency Info:', dependencyInfo);
  }, []);

  return (
    <div>
      <Content content="Hello from loader!" />
    </div>
  );
}
```

### Using Environment Configuration

```tsx
import React from 'react';
import { initialize, getContent, Environment } from 'oatfi-loader';

// Initialize the loader with environment-specific configuration
initialize({
  oatfiComponentsUrl: Environment.API_URL,
  fallback: <div>Loading components...</div>
});

function App() {
  const Content = getContent();

  return (
    <div>
      <Content content="Hello from loader!" />
    </div>
  );
}
```

## How It Works

The loader automatically:

1. **Detects host React instances** from the consuming application
2. **Sets up shared dependencies** to prevent React duplication
3. **Sets up module federation remotes** at runtime without requiring webpack configuration
4. **Dynamically loads remote entry scripts** from the specified URLs
5. **Handles module resolution** through the module federation protocol
6. **Provides a simple API** to consume federated components

## Shared Dependency Management

The oatfi-loader automatically handles shared dependencies:

- **Automatic Detection**: Finds React instances in the host application
- **Version Checking**: Verifies React version compatibility
- **Graceful Fallbacks**: Uses local React if host React is incompatible
- **Singleton Behavior**: Ensures only one React instance is loaded
- **Error Handling**: Gracefully handles dependency conflicts

## API Reference

### Functions

#### `initialize(config?: LoaderConfig)`
Initialize the module federation loader with optional configuration.

#### `getContent(): ContentComponent`
Get the Content component from Oatfi Components.

#### `getSharedDependencyInfo(): SharedDependencyInfo`
Get information about shared dependencies for debugging.

### Constants

#### `Environment`
Environment configuration from the Oatfi SDK.

### Classes

#### `ModuleFederationLoader`
Main loader class that handles module federation setup.

**Methods:**
- `initialize()`: Initialize the loader
- `getContent()`: Get Content component
- `updateConfig(config: Partial<LoaderConfig>)`: Update configuration
- `getSharedDependencyInfo()`: Get shared dependency information

### Types

#### `LoaderConfig`
```typescript
interface LoaderConfig {
  oatfiComponentsUrl?: string;  // URL for Oatfi Components (default: http://localhost:3001)
  fallback?: React.ReactNode;   // Fallback component while loading
}
```

#### `ContentProps`
```typescript
interface ContentProps {
  content?: string;
}
```

#### `SharedDependencyInfo`
```typescript
interface SharedDependencyInfo {
  hostReact: boolean;           // Whether host React was detected
  hostReactDOM: boolean;        // Whether host React-DOM was detected
  reactVersion?: string;        // React version from host
  sharedModulesInitialized: boolean; // Whether shared modules are initialized
  sharedModules: any;           // Shared modules registry
}
```

## Prerequisites

Make sure you have the following running:
- Oatfi Components on http://localhost:3001 (or your custom URL)

The app should be built and serving its module federation remote entries.

## Troubleshooting

### "Module not found" errors

If you're getting "Module not found" errors for `oatfiComponents/Content`, make sure:

1. The remote app (Oatfi Components) is running and accessible
2. The remote entry URL is correct in your configuration
3. You're calling `initialize()` before using the components
4. Check that the remote app is properly exposing the Content component

### Runtime errors

If you're getting runtime errors about remotes not being available:

1. Check that the remote app is running
2. Verify the URL in your configuration
3. Check browser console for any network errors
4. Ensure the remote app is properly configured to expose the Content component

### Shared dependency issues

If you're experiencing React-related issues:

1. Check the console for shared dependency information using `getSharedDependencyInfo()`
2. Verify React version compatibility between host and remote
3. Look for warnings about version mismatches
4. The loader will automatically fall back to local React if needed

### CORS issues

If you're getting CORS errors:

1. Make sure the remote app allows cross-origin requests
2. Check that the remote entry URL is accessible from your consuming app
3. Verify that the remote app is properly configured for module federation

## Development

```bash
# Install dependencies
npm install

# Build the project
npm run build

# Watch for changes
npm run dev

# Clean build artifacts
npm run clean

# Create package
npm run pack
```

## License

MIT