CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-pmmmwh--react-refresh-webpack-plugin

Webpack plugin to enable React Fast Refresh (Hot Reloading) for React components during development

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

runtime-utilities.mddocs/

Runtime Utilities

React Refresh runtime utilities that handle module boundary detection, component registration, and hot reload coordination at runtime.

Capabilities

Enqueue Update

Schedules a React Refresh update to be processed during the next update cycle.

/**
 * Enqueues a React component update for processing
 * @returns {void}
 */
function enqueueUpdate(): void;

Usage Example:

const RefreshUtils = require('@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils');

// Trigger a refresh update
RefreshUtils.enqueueUpdate();

Execute Runtime

Executes the React Refresh runtime, processing any pending updates and refreshing affected components.

/**
 * Executes the React Refresh runtime to process pending updates
 * @returns {void}
 */
function executeRuntime(): void;

Usage Example:

const RefreshUtils = require('@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils');

// Execute runtime after module updates
RefreshUtils.executeRuntime();

Get Module Exports

Retrieves the current exports of a webpack module by its ID.

/**
 * Gets the current exports of a webpack module
 * @param {string} moduleId - The webpack module identifier
 * @returns {any} - The module's current exports
 */
function getModuleExports(moduleId: string): any;

Usage Example:

const RefreshUtils = require('@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils');

// Get module exports for inspection
const moduleExports = RefreshUtils.getModuleExports('./src/components/Button.jsx');
console.log('Button component exports:', moduleExports);

Is React Refresh Boundary

Determines whether a module's exports constitute a valid React Refresh boundary (i.e., contains React components).

/**
 * Checks if module exports represent a React Refresh boundary
 * @param {any} moduleExports - The exports to check
 * @returns {boolean} - True if exports form a valid refresh boundary
 */
function isReactRefreshBoundary(moduleExports: any): boolean;

Usage Example:

const RefreshUtils = require('@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils');

// Check if a module is a React component boundary
const ButtonExports = require('./Button.jsx');
const isRefreshable = RefreshUtils.isReactRefreshBoundary(ButtonExports);

console.log('Button is refreshable:', isRefreshable);

// Non-React modules return false
const utilsExports = require('./utils.js');
const isUtilsRefreshable = RefreshUtils.isReactRefreshBoundary(utilsExports);
console.log('Utils is refreshable:', isUtilsRefreshable); // false

Register Exports For React Refresh

Registers a module's exports with the React Refresh runtime for hot reloading.

/**
 * Registers module exports with React Refresh runtime
 * @param {string} moduleId - The webpack module identifier
 * @param {any} moduleExports - The module's exports to register
 * @returns {void}
 */
function registerExportsForReactRefresh(moduleId: string, moduleExports: any): void;

Usage Example:

const RefreshUtils = require('@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils');

// Register React component for refresh
const MyComponent = require('./MyComponent.jsx');
RefreshUtils.registerExportsForReactRefresh('./src/MyComponent.jsx', MyComponent);

// Typically used in module hot accept callbacks
if (module.hot) {
  module.hot.accept('./MyComponent.jsx', () => {
    const UpdatedComponent = require('./MyComponent.jsx');
    RefreshUtils.registerExportsForReactRefresh('./src/MyComponent.jsx', UpdatedComponent);
    RefreshUtils.enqueueUpdate();
  });
}

Advanced Usage Patterns

Custom Module Hot Reload Logic

Implement custom hot reload logic using runtime utilities:

const RefreshUtils = require('@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils');

function handleModuleUpdate(moduleId, newExports) {
  // Check if module can be hot reloaded
  if (RefreshUtils.isReactRefreshBoundary(newExports)) {
    console.log(`Module ${moduleId} is refreshable`);
    
    // Register updated exports
    RefreshUtils.registerExportsForReactRefresh(moduleId, newExports);
    
    // Trigger refresh
    RefreshUtils.enqueueUpdate();
    RefreshUtils.executeRuntime();
  } else {
    console.log(`Module ${moduleId} requires full reload`);
    window.location.reload();
  }
}

// Usage in webpack HMR accept callback
if (module.hot) {
  module.hot.accept(['./ComponentA.jsx', './ComponentB.jsx'], (updatedDependencies) => {
    updatedDependencies.forEach(moduleId => {
      const newExports = RefreshUtils.getModuleExports(moduleId);
      handleModuleUpdate(moduleId, newExports);
    });
  });
}

Component Boundary Detection

Detect and categorize different types of module exports:

const RefreshUtils = require('@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils');

function categorizeModule(moduleExports, moduleId) {
  if (RefreshUtils.isReactRefreshBoundary(moduleExports)) {
    return {
      type: 'react-component',
      refreshable: true,
      moduleId,
      exports: moduleExports
    };
  }
  
  // Check for higher-order components or hooks
  if (typeof moduleExports === 'function' && moduleExports.name.startsWith('use')) {
    return {
      type: 'react-hook',
      refreshable: true, // Hooks can be refreshed
      moduleId,
      exports: moduleExports
    };
  }
  
  return {
    type: 'utility',
    refreshable: false,
    moduleId,
    exports: moduleExports
  };
}

// Categorize current module
const moduleInfo = categorizeModule(module.exports, module.id);
console.log('Module info:', moduleInfo);

if (moduleInfo.refreshable) {
  RefreshUtils.registerExportsForReactRefresh(moduleInfo.moduleId, moduleInfo.exports);
}

Batch Update Processing

Process multiple module updates efficiently:

const RefreshUtils = require('@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils');

class RefreshBatchProcessor {
  constructor() {
    this.pendingUpdates = new Set();
    this.processingTimeout = null;
  }
  
  addUpdate(moduleId, moduleExports) {
    // Register the module
    if (RefreshUtils.isReactRefreshBoundary(moduleExports)) {
      RefreshUtils.registerExportsForReactRefresh(moduleId, moduleExports);
      this.pendingUpdates.add(moduleId);
      
      // Schedule batch processing
      this.scheduleBatchProcess();
    }
  }
  
  scheduleBatchProcess() {
    if (this.processingTimeout) {
      clearTimeout(this.processingTimeout);
    }
    
    this.processingTimeout = setTimeout(() => {
      this.processBatch();
    }, 10); // Small delay to batch multiple updates
  }
  
  processBatch() {
    if (this.pendingUpdates.size > 0) {
      console.log(`Processing ${this.pendingUpdates.size} pending updates`);
      
      // Single enqueue and execute for all updates
      RefreshUtils.enqueueUpdate();
      RefreshUtils.executeRuntime();
      
      this.pendingUpdates.clear();
    }
    this.processingTimeout = null;
  }
}

// Global batch processor
const batchProcessor = new RefreshBatchProcessor();

// Use in HMR callbacks
if (module.hot) {
  module.hot.accept(['./ComponentA.jsx', './ComponentB.jsx'], () => {
    const ComponentA = RefreshUtils.getModuleExports('./ComponentA.jsx');
    const ComponentB = RefreshUtils.getModuleExports('./ComponentB.jsx');
    
    batchProcessor.addUpdate('./ComponentA.jsx', ComponentA);
    batchProcessor.addUpdate('./ComponentB.jsx', ComponentB);
  });
}

Runtime Integration

These utilities are typically used by the webpack loader and runtime modules automatically, but can be used directly for advanced customization:

// Custom loader or plugin integration
const RefreshUtils = require('@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils');

// In a custom webpack loader
module.exports = function customReactLoader(source) {
  if (this.mode === 'development') {
    // Add runtime registration code
    const refreshCode = `
      const RefreshUtils = require('@pmmmwh/react-refresh-webpack-plugin/lib/runtime/RefreshUtils');
      
      if (RefreshUtils.isReactRefreshBoundary(module.exports)) {
        RefreshUtils.registerExportsForReactRefresh(module.id, module.exports);
        
        if (module.hot) {
          module.hot.accept(() => {
            RefreshUtils.enqueueUpdate();
            RefreshUtils.executeRuntime();
          });
        }
      }
    `;
    
    return source + '\n\n' + refreshCode;
  }
  
  return source;
};

Install with Tessl CLI

npx tessl i tessl/npm-pmmmwh--react-refresh-webpack-plugin

docs

client-utilities.md

error-overlay.md

index.md

loader-configuration.md

plugin-configuration.md

plugin-utilities.md

runtime-utilities.md

socket-integrations.md

tile.json