npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@expozr/webpack-adapter

v2.2.0

Published

Webpack adapter for the Expozr ecosystem

Readme

@expozr/webpack-adapter

npm version License: MIT

Webpack integration for the Expozr module federation ecosystem

The Webpack adapter provides seamless integration between Webpack and the Expozr module federation system. It enables you to build and consume federated modules with Webpack's mature ecosystem, robust optimization features, and extensive plugin architecture.

Features

  • 🎯 UMD-First Architecture: Optimized UMD builds for maximum Navigator compatibility
  • 🔧 Automatic Configuration: Zero-config setup with intelligent defaults
  • 🌐 Development Server Integration: Hot reloading with CORS support
  • 📦 Inventory Management: Automatic generation and serving of module inventories
  • 🔗 Expozr & Host Support: Both module producers and consumers
  • Production Optimized: Tree-shaking and code-splitting ready
  • 🛡️ Type Safety: Full TypeScript support with optimized configurations
  • 🎨 Developer Experience: Warning suppression and clear error messages
  • 🌍 Cross-Origin Ready: Built-in CORS configuration for distributed deployments

Installation

npm install @expozr/webpack-adapter
# or
yarn add @expozr/webpack-adapter
# or
pnpm add @expozr/webpack-adapter

Quick Start

Expozr (Module Producer)

Create an expozr that exposes modules to be consumed by other applications:

// webpack.config.js
const { createExpozrPlugin } = require("@expozr/webpack-adapter");

module.exports = {
  entry: "./src/index.ts",
  mode: "development",
  plugins: [
    createExpozrPlugin(), // Auto-discovers expozr.config.ts
  ],
  devServer: {
    port: 3001,
  },
};
// expozr.config.ts
import { defineConfig } from "@expozr/core";

export default defineConfig({
  name: "my-expozr",
  expose: {
    "./Button": "./src/components/Button.tsx",
    "./utils": "./src/utils/index.ts",
  },
  build: {
    format: ["umd"], // UMD for optimal Navigator compatibility
    outDir: "dist",
  },
});

Host (Module Consumer)

Create a host application that consumes remote modules:

// webpack.config.js
const {
  createHostPlugin,
  createHostWebpackConfig,
} = require("@expozr/webpack-adapter");

module.exports = createHostWebpackConfig({
  entry: "./src/index.ts",
  plugins: [
    createHostPlugin({
      config: {
        expozrs: {
          "design-system": {
            url: "http://localhost:3001",
          },
          "shared-utils": {
            url: "https://cdn.example.com/utils",
          },
        },
      },
    }),
  ],
});

API Reference

Plugins

createExpozrPlugin(options)

Creates a webpack plugin for expozr applications that expose federated modules.

Options:

  • configFile?: string - Path to Expozr config file (default: auto-discovery)
  • config?: ExpozrConfig - Direct config object (overrides configFile)
  • outputPath?: string - Custom output path (overrides config)
  • publicPath?: string - Custom public path (overrides config)

Example:

const { createExpozrPlugin } = require("@expozr/webpack-adapter");

// Basic usage - auto-discovers expozr.config.ts
createExpozrPlugin();

// Custom config file
createExpozrPlugin({
  configFile: "./my-expozr.config.js",
});

// Direct configuration
createExpozrPlugin({
  config: {
    name: "my-expozr",
    expose: {
      "./Component": "./src/Component.tsx",
    },
  },
});

createHostPlugin(options)

Creates a webpack plugin for host applications that consume remote federated modules.

Options:

  • configFile?: string - Path to host config file
  • config?: HostConfig - Direct config object (overrides configFile)

Example:

const { createHostPlugin } = require("@expozr/webpack-adapter");

createHostPlugin({
  config: {
    expozrs: {
      "ui-components": {
        url: "http://localhost:4000",
      },
      "business-logic": {
        url: "https://api.example.com/modules",
      },
    },
  },
});

Adapter Class

WebpackAdapter

The main adapter class implementing the Expozr bundler adapter interface.

const { WebpackAdapter } = require("@expozr/webpack-adapter");

const adapter = new WebpackAdapter();

// Configure for expozr build
const expozrWebpackConfig = adapter.configureExpozr(
  expozrConfig,
  baseWebpackConfig
);

// Configure for host build
const hostWebpackConfig = adapter.configureHost(hostConfig, baseWebpackConfig);

// Check if webpack is available
console.log("Webpack available:", adapter.isAvailable());

Methods:

  • configureExpozr(config, bundlerConfig) - Configure webpack for expozr builds
  • configureHost(config, bundlerConfig) - Configure webpack for host builds
  • getDefaultConfig() - Get default webpack configuration
  • isAvailable() - Check if webpack is available
  • createExpozrPlugin(config) - Create ExpozrPlugin instance
  • createHostPlugin(config) - Create ExpozrHostPlugin instance
  • getIgnoreWarnings() - Get warning suppressions for better DX

Utility Functions

createHostWebpackConfig(customConfig)

Creates a webpack configuration optimized for Expozr host applications with sensible defaults.

const { createHostWebpackConfig } = require("@expozr/webpack-adapter");

module.exports = createHostWebpackConfig({
  entry: "./src/app.tsx",
  plugins: [
    // your plugins
  ],
  devServer: {
    port: 3000,
  },
});

Features:

  • Pre-configured TypeScript support
  • CORS headers for development
  • Dynamic import support
  • Warning suppression
  • Optimized resolve configuration

suppressExpozrWarnings()

Returns ignoreWarnings configuration to suppress common Expozr-related webpack warnings.

const { suppressExpozrWarnings } = require("@expozr/webpack-adapter");

module.exports = {
  // ... your webpack config
  ignoreWarnings: [
    ...suppressExpozrWarnings(),
    // your custom warning filters
  ],
};

Configuration

Expozr Configuration

Your expozr.config.ts file defines what modules to expose and how to build them:

import { defineConfig } from "@expozr/core";

export default defineConfig({
  name: "my-design-system",

  // Modules to expose
  expose: {
    "./Button": "./src/components/Button/index.tsx",
    "./Input": "./src/components/Input/index.tsx",
    "./Theme": "./src/theme/index.ts",
    "./utils/validators": "./src/utils/validators.ts",
  },

  // Build configuration
  build: {
    format: ["umd"], // UMD recommended for webpack + Navigator
    target: "web", // Target environment
    outDir: "dist", // Output directory
    publicPath: "/", // Public path for assets
    sourcemap: true, // Generate sourcemaps
    minify: false, // Minification (use webpack optimization instead)
  },

  // Module system configuration
  moduleSystem: {
    primary: "umd",
    fallbacks: ["esm"],
    strategy: "dynamic",
  },

  // Dependencies configuration
  dependencies: {
    react: "^18.0.0",
    "react-dom": "^18.0.0",
  },
});

Host Configuration

Configure which expozrs your host application consumes:

interface HostConfig {
  expozrs: {
    [expozrName: string]: {
      url: string; // Expozr URL
      scope?: string; // Optional scope for name resolution
      timeout?: number; // Request timeout in ms
      retries?: number; // Number of retry attempts
      version?: string; // Version constraint (semver)
      fallback?: string; // Fallback URL
    };
  };

  // Optional catalog configuration
  catalog?: {
    url: string;
    refreshInterval?: number;
  };

  // Cache configuration
  cache?: {
    strategy: "memory" | "localStorage" | "indexedDB";
    ttl?: number;
  };
}

Webpack Configuration

The adapter integrates seamlessly with your existing webpack configuration:

// webpack.config.js
const path = require("path");
const {
  createExpozrPlugin,
  suppressExpozrWarnings,
} = require("@expozr/webpack-adapter");

module.exports = {
  entry: "./src/index.ts",
  mode: "development",

  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: "ts-loader",
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },

  resolve: {
    extensions: [".tsx", ".ts", ".js"],
    alias: {
      "@": path.resolve(__dirname, "src"),
    },
  },

  plugins: [
    createExpozrPlugin({
      configFile: "./expozr.config.ts",
    }),
  ],

  // Suppress Expozr-related warnings for cleaner output
  ignoreWarnings: suppressExpozrWarnings(),

  // UMD-optimized output
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "[name].js",
    library: {
      name: "[name]",
      type: "umd",
    },
    globalObject: "typeof self !== 'undefined' ? self : this",
    clean: true,
  },

  // Development server with CORS
  devServer: {
    port: 3001,
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "*",
      "Access-Control-Allow-Headers": "*",
    },
    static: {
      directory: path.join(__dirname, "dist"),
    },
  },

  // Production optimizations
  optimization: {
    // Disable optimizations that break UMD
    concatenateModules: false,
    usedExports: false,
    sideEffects: false,
    splitChunks: false,
    runtimeChunk: false,
  },
};

Advanced Configuration

Multiple Output Formats

While UMD is recommended for maximum compatibility, you can configure multiple formats:

// expozr.config.ts
export default defineConfig({
  name: "multi-format-expozr",
  expose: {
    "./utils": "./src/utils.ts",
  },
  build: {
    format: ["umd", "esm"], // Multiple formats
    outDir: "dist",
  },
});

The webpack adapter will generate:

  • dist/utils.js (UMD format)
  • dist/utils.mjs (ESM format)

TypeScript Integration

The adapter automatically configures TypeScript for optimal expozr builds:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: [
          {
            loader: "ts-loader",
            options: {
              // The adapter optimizes these settings
              compilerOptions: {
                target: "es2018",
                module: "esnext",
                moduleResolution: "node",
                declaration: true,
                declarationMap: true,
              },
            },
          },
        ],
      },
    ],
  },
};

External Dependencies

Configure external dependencies to avoid bundling common libraries:

// webpack.config.js
module.exports = {
  externals: {
    react: {
      commonjs: "react",
      commonjs2: "react",
      amd: "react",
      root: "React", // Global variable name
    },
    "react-dom": {
      commonjs: "react-dom",
      commonjs2: "react-dom",
      amd: "react-dom",
      root: "ReactDOM",
    },
  },
};

Production Optimization

For production builds, enable webpack's optimization features:

// webpack.config.js
const TerserPlugin = require("terser-webpack-plugin");

module.exports = {
  mode: "production",

  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            drop_console: true, // Remove console.log
          },
          format: {
            comments: false, // Remove comments
          },
        },
        extractComments: false,
      }),
    ],

    // Enable these optimizations carefully with UMD
    usedExports: true,
    sideEffects: false,
  },
};

Development Workflow

Local Development

  1. Start the expozr development server:

    cd packages/my-expozr
    npm run dev  # webpack serve
  2. Start the host application:

    cd apps/host-app
    npm run dev
  3. Access inventory endpoint:

    http://localhost:3001/inventory.json

Production Deployment

  1. Build the expozr:

    npm run build  # webpack --mode=production
  2. Deploy static files:

    # Deploy dist/ folder to CDN or static hosting
    aws s3 sync dist/ s3://my-expozr-bucket/
  3. Update host configuration:

    const config = {
      expozrs: {
        "my-expozr": {
          url: "https://cdn.example.com/my-expozr",
        },
      },
    };

Troubleshooting

Common Issues

1. Module Not Found Errors

Problem: Module not found: Error: Can't resolve 'my-expozr/Button'

Solution: Ensure the expozr is running and the inventory is accessible:

# Check if inventory is available
curl http://localhost:3001/inventory.json

# Verify the expose configuration
cat expozr.config.ts

2. CORS Errors

Problem: Access to fetch at 'http://localhost:3001' from origin 'http://localhost:3000' has been blocked by CORS policy

Solution: The adapter automatically configures CORS headers, but verify your setup:

// webpack.config.js
module.exports = {
  devServer: {
    headers: {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
      "Access-Control-Allow-Headers":
        "X-Requested-With, content-type, Authorization",
    },
  },
};

3. UMD Global Issues

Problem: Cannot read property 'Button' of undefined when accessing UMD exports

Solution: Verify your library configuration:

// webpack.config.js
module.exports = {
  output: {
    library: {
      name: "MyExpozr", // Must match what host expects
      type: "umd",
    },
    globalObject: "typeof self !== 'undefined' ? self : this",
  },
};

4. TypeScript Declaration Issues

Problem: Missing or incorrect TypeScript declarations

Solution: Enable declaration generation:

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        use: {
          loader: "ts-loader",
          options: {
            compilerOptions: {
              declaration: true,
              declarationMap: true,
              outDir: "dist/types",
            },
          },
        },
      },
    ],
  },
};

Performance Tips

  1. Use webpack-bundle-analyzer to understand bundle size:

    npm install --save-dev webpack-bundle-analyzer
  2. Enable tree-shaking for smaller bundles:

    module.exports = {
      optimization: {
        usedExports: true,
        sideEffects: false, // or array of files with side effects
      },
    };
  3. Use dynamic imports for code splitting:

    // Instead of static imports
    import { heavyUtility } from "./heavy-utils";
    
    // Use dynamic imports
    const loadHeavyUtility = () => import("./heavy-utils");

Comparison with Other Bundlers

| Feature | Webpack | Vite | Rollup | | ---------------------------- | ------------ | ------------ | ------------ | | UMD Support | ✅ Excellent | ⚠️ Limited | ✅ Good | | Development Speed | ⚠️ Moderate | ✅ Very Fast | ⚠️ Moderate | | Production Optimization | ✅ Excellent | ✅ Good | ✅ Excellent | | Plugin Ecosystem | ✅ Massive | ✅ Growing | ✅ Good | | Configuration Complexity | ⚠️ High | ✅ Low | ⚠️ Moderate | | Navigator Compatibility | ✅ Perfect | ✅ Good | ✅ Good |

When to Choose Webpack

Choose webpack when you:

  • Need maximum UMD compatibility
  • Have complex build requirements
  • Use advanced webpack features (federation, workers, etc.)
  • Require extensive plugin ecosystem
  • Need mature production optimizations
  • Have existing webpack expertise in your team

Consider alternatives when you:

  • Want the fastest development experience (→ Vite)
  • Need the smallest bundle sizes (→ Rollup)
  • Prefer minimal configuration (→ Vite)

Examples

Check out the examples directory for complete working examples:

Migration Guide

From Webpack Module Federation

If you're migrating from webpack's native Module Federation:

// Before: webpack.config.js with ModuleFederationPlugin
module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: "myExpozr",
      filename: "remoteEntry.js",
      exposes: {
        "./Button": "./src/Button.tsx",
      },
    }),
  ],
};

// After: webpack.config.js with Expozr
module.exports = {
  plugins: [
    createExpozrPlugin(), // Uses expozr.config.ts
  ],
};
// Create: expozr.config.ts
export default defineConfig({
  name: "myExpozr",
  expose: {
    "./Button": "./src/Button.tsx",
  },
});

From Other Bundlers

See the migration guide for detailed instructions on migrating from other bundlers.

Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

  1. Clone the repository:

    git clone https://github.com/brunos3d/expozr.git
    cd expozr
  2. Install dependencies:

    npm install
  3. Build the webpack adapter:

    cd packages/adapters/webpack
    npm run build
  4. Run tests:

    npm test

License

MIT © Bruno Silva

Related