hot-reload-optimizer

Optimize development experience with fast hot module replacement.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "hot-reload-optimizer" with this command: npx skills add monkey1sai/openai-cli/monkey1sai-openai-cli-hot-reload-optimizer

Hot Reload Optimizer

Optimize development experience with fast hot module replacement.

Core Workflow

  • Analyze bottlenecks: Identify slow rebuilds

  • Configure HMR: Framework-specific setup

  • Optimize bundler: Exclude heavy dependencies

  • Setup caching: Persistent caching

  • Monitor performance: Dev server metrics

  • Fine-tune: Incremental improvements

Vite Configuration

// vite.config.ts import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react'; import tsconfigPaths from 'vite-tsconfig-paths';

export default defineConfig({ plugins: [ react({ // Use SWC for faster transforms jsxRuntime: 'automatic', // Fast Refresh options fastRefresh: true, }), tsconfigPaths(), ],

// Optimize dependencies optimizeDeps: { // Pre-bundle these dependencies include: [ 'react', 'react-dom', 'react-router-dom', '@tanstack/react-query', 'zustand', 'lodash-es', ], // Exclude from pre-bundling exclude: ['@vite/client'], // Force re-optimization force: false, // Increase timeout for slow deps entries: ['./src/**/*.{ts,tsx}'], },

// Server configuration server: { port: 3000, // Enable HMR hmr: { overlay: true, protocol: 'ws', host: 'localhost', }, // Watch options watch: { // Use polling in containers/VMs usePolling: false, // Ignore patterns ignored: ['/node_modules/', '/.git/'], }, // Faster startup warmup: { clientFiles: ['./src/main.tsx', './src/App.tsx'], }, },

// Build optimizations for dev build: { // Source maps for development sourcemap: true, // Chunk size warnings chunkSizeWarningLimit: 1000, },

// Resolve configuration resolve: { alias: { '@': '/src', }, },

// CSS configuration css: { devSourcemap: true, modules: { localsConvention: 'camelCase', }, },

// Define environment variables define: { DEV: JSON.stringify(process.env.NODE_ENV !== 'production'), }, });

Vite with SWC

// vite.config.ts with SWC import { defineConfig } from 'vite'; import react from '@vitejs/plugin-react-swc';

export default defineConfig({ plugins: [ react({ // SWC options jsxImportSource: '@emotion/react', plugins: [ // SWC plugins ['@swc/plugin-emotion', {}], ], }), ], });

Next.js Configuration

// next.config.js /** @type {import('next').NextConfig} */ const nextConfig = { // Enable SWC compiler swcMinify: true,

// Experimental features for faster dev experimental: { // Turbopack (when stable) // turbo: {},

// Optimize package imports
optimizePackageImports: [
  '@heroicons/react',
  'lucide-react',
  'date-fns',
  'lodash',
],

},

// Webpack customization webpack: (config, { dev, isServer }) => { if (dev) { // Faster source maps in development config.devtool = 'eval-source-map';

  // Ignore large modules in watch
  config.watchOptions = {
    ignored: ['**/node_modules/**', '**/.git/**'],
    aggregateTimeout: 200,
    poll: false,
  };

  // Cache configuration
  config.cache = {
    type: 'filesystem',
    buildDependencies: {
      config: [__filename],
    },
  };
}

return config;

},

// Disable type checking during dev (use IDE) typescript: { ignoreBuildErrors: process.env.NODE_ENV === 'development', },

// Disable linting during dev (use IDE) eslint: { ignoreDuringBuilds: process.env.NODE_ENV === 'development', },

// Image optimization images: { domains: ['example.com'], deviceSizes: [640, 750, 828, 1080, 1200], }, };

module.exports = nextConfig;

Next.js Turbopack

// next.config.js with Turbopack /** @type {import('next').NextConfig} / const nextConfig = { experimental: { turbo: { rules: { '.svg': { loaders: ['@svgr/webpack'], as: '*.js', }, }, resolveAlias: { '@': './src', }, }, }, };

module.exports = nextConfig;

Run with Turbopack

next dev --turbo

Webpack Configuration

// webpack.config.js const path = require('path'); const webpack = require('webpack'); const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');

module.exports = (env, argv) => { const isDev = argv.mode === 'development';

return { mode: isDev ? 'development' : 'production',

// Fast rebuild source maps
devtool: isDev ? 'eval-cheap-module-source-map' : 'source-map',

entry: './src/index.tsx',

output: {
  path: path.resolve(__dirname, 'dist'),
  filename: isDev ? '[name].js' : '[name].[contenthash].js',
  clean: true,
},

// Caching for faster rebuilds
cache: isDev ? {
  type: 'filesystem',
  cacheDirectory: path.resolve(__dirname, '.cache'),
  buildDependencies: {
    config: [__filename],
  },
} : false,

// Module resolution
resolve: {
  extensions: ['.tsx', '.ts', '.js'],
  alias: {
    '@': path.resolve(__dirname, 'src'),
  },
},

module: {
  rules: [
    {
      test: /\.[jt]sx?$/,
      exclude: /node_modules/,
      use: {
        loader: 'swc-loader',
        options: {
          jsc: {
            parser: {
              syntax: 'typescript',
              tsx: true,
            },
            transform: {
              react: {
                runtime: 'automatic',
                development: isDev,
                refresh: isDev,
              },
            },
          },
        },
      },
    },
    {
      test: /\.css$/,
      use: ['style-loader', 'css-loader', 'postcss-loader'],
    },
  ],
},

plugins: [
  // React Fast Refresh
  isDev && new ReactRefreshPlugin({
    overlay: {
      sockIntegration: 'whm',
    },
  }),

  // TypeScript type checking in separate process
  isDev && new ForkTsCheckerWebpackPlugin({
    async: true,
    typescript: {
      configFile: path.resolve(__dirname, 'tsconfig.json'),
      diagnosticOptions: {
        semantic: true,
        syntactic: true,
      },
    },
  }),

  // HMR
  isDev && new webpack.HotModuleReplacementPlugin(),
].filter(Boolean),

// Dev server configuration
devServer: {
  port: 3000,
  hot: true,
  liveReload: false, // Use HMR instead
  client: {
    overlay: {
      errors: true,
      warnings: false,
    },
    progress: true,
  },
  static: {
    directory: path.join(__dirname, 'public'),
  },
  historyApiFallback: true,
  compress: true,
  watchFiles: ['src/**/*'],
},

// Optimization
optimization: {
  moduleIds: 'deterministic',
  runtimeChunk: 'single',
  splitChunks: {
    cacheGroups: {
      vendor: {
        test: /[\\/]node_modules[\\/]/,
        name: 'vendors',
        chunks: 'all',
      },
    },
  },
},

// Performance hints
performance: {
  hints: isDev ? false : 'warning',
},

// Stats configuration
stats: isDev ? 'errors-warnings' : 'normal',

}; };

React Fast Refresh Boundaries

// src/components/ErrorBoundary.tsx import { Component, type ErrorInfo, type ReactNode } from 'react';

interface Props { children: ReactNode; fallback?: ReactNode; }

interface State { hasError: boolean; }

export class ErrorBoundary extends Component<Props, State> { state: State = { hasError: false };

static getDerivedStateFromError(): State { return { hasError: true }; }

componentDidCatch(error: Error, errorInfo: ErrorInfo) { console.error('Error caught by boundary:', error, errorInfo); }

render() { if (this.state.hasError) { return this.props.fallback ?? <div>Something went wrong</div>; }

return this.props.children;

} }

// Fast Refresh will reset error boundaries automatically

// src/App.tsx - Proper export for Fast Refresh import { useState } from 'react';

// Named export works with Fast Refresh export function App() { const [count, setCount] = useState(0);

return ( <div> <h1>Count: {count}</h1> <button onClick={() => setCount(c => c + 1)}>Increment</button> </div> ); }

// Don't mix component and non-component exports in same file // This breaks Fast Refresh: // export const API_URL = 'https://api.example.com';

CSS HMR Optimization

// vite.config.ts - CSS optimization export default defineConfig({ css: { // Enable CSS source maps devSourcemap: true,

// PostCSS configuration
postcss: {
  plugins: [
    require('tailwindcss'),
    require('autoprefixer'),
  ],
},

// CSS Modules
modules: {
  localsConvention: 'camelCase',
  generateScopedName: '[name]__[local]___[hash:base64:5]',
},

}, });

// tailwind.config.js - Optimize for HMR module.exports = { content: ['./src/**/*.{js,ts,jsx,tsx}'],

// JIT mode is default in v3+ // Reduces CSS generation time

// Disable unused features corePlugins: { preflight: true, // Disable unused utilities // float: false, // clear: false, }, };

Development Scripts

// package.json { "scripts": { "dev": "vite --host", "dev:debug": "DEBUG=vite:* vite", "dev:profile": "vite --profile", "dev:force": "vite --force", "analyze": "vite-bundle-analyzer", "typecheck": "tsc --noEmit --watch", "typecheck:fast": "tsc --noEmit --incremental" } }

Performance Monitoring

// vite.config.ts - Plugin for performance monitoring import { defineConfig, type Plugin } from 'vite';

function hmrTimingPlugin(): Plugin { let startTime: number;

return { name: 'hmr-timing', handleHotUpdate({ file }) { startTime = performance.now(); console.log([HMR] File changed: ${file}); return; }, transform() { if (startTime) { const duration = performance.now() - startTime; console.log([HMR] Transform took: ${duration.toFixed(2)}ms); } return null; }, }; }

export default defineConfig({ plugins: [hmrTimingPlugin()], });

// src/dev-utils.ts - Client-side HMR monitoring if (import.meta.hot) { let lastUpdate = Date.now();

import.meta.hot.on('vite:beforeUpdate', () => { lastUpdate = Date.now(); console.log('[HMR] Update starting...'); });

import.meta.hot.on('vite:afterUpdate', () => { const duration = Date.now() - lastUpdate; console.log([HMR] Update complete in ${duration}ms); });

import.meta.hot.on('vite:error', (error) => { console.error('[HMR] Error:', error); }); }

Docker Development

Dockerfile.dev

FROM node:20-alpine

WORKDIR /app

Install dependencies separately for caching

COPY package*.json ./ RUN npm ci

Copy source

COPY . .

Use polling for file watching in Docker

ENV CHOKIDAR_USEPOLLING=true ENV WATCHPACK_POLLING=true

EXPOSE 3000

CMD ["npm", "run", "dev"]

docker-compose.dev.yml

services: app: build: context: . dockerfile: Dockerfile.dev volumes: # Mount source for HMR - ./src:/app/src - ./public:/app/public # Exclude node_modules - /app/node_modules ports: - "3000:3000" environment: - CHOKIDAR_USEPOLLING=true - WATCHPACK_POLLING=true

Best Practices

  • Use SWC/esbuild: Faster than Babel

  • Pre-bundle dependencies: Avoid re-bundling

  • Filesystem caching: Persist build cache

  • Separate type checking: Fork process

  • Optimize imports: Tree-shake properly

  • Minimize watchers: Exclude unnecessary files

  • Use Turbopack: When stable in Next.js

  • Profile regularly: Identify bottlenecks

Output Checklist

Every HMR optimization should include:

  • Fast compiler (SWC/esbuild)

  • Dependency pre-bundling

  • Filesystem cache enabled

  • Source maps configured

  • Watch options optimized

  • Type checking separated

  • CSS HMR working

  • Error overlay configured

  • Docker polling setup

  • Performance monitoring

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

responsive-design-system

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

rate-limiting-abuse-protection

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

bruno-collection-generator

No summary provided by upstream source.

Repository SourceNeeds Review