常见问题排查

在使用 Webpack 的过程中,经常会遇到各种问题。本章整理常见问题及其解决方案,帮助你快速解决问题。


📋 常见问题


路径解析问题

问题:Module not found

错误信息

Module not found: Error: Can't resolve './components/Button'

解决方案

  1. 检查路径是否正确
// ❌ 错误
import Button from './components/Button'
 
// ✅ 正确
import Button from './components/Button.js'
// 或配置 extensions
  1. 配置 resolve.extensions
module.exports = {
  resolve: {
    extensions: ['.js', '.jsx', '.json', '.ts', '.tsx']
  }
}
  1. 配置路径别名
module.exports = {
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src'),
      '@components': path.resolve(__dirname, 'src/components')
    }
  }
}

依赖冲突

问题:多个版本的同一依赖

错误信息

Module not found: Can't resolve 'react'

解决方案

  1. 使用 resolve.alias 强制使用指定版本
module.exports = {
  resolve: {
    alias: {
      'react': path.resolve(__dirname, 'node_modules/react')
    }
  }
}
  1. 检查 package.json
npm ls react
  1. 使用 npm dedupe
npm dedupe
  1. 删除 node_modules 重新安装
rm -rf node_modules package-lock.json
npm install

构建速度慢

问题:构建时间过长

解决方案

  1. 启用缓存
module.exports = {
  cache: {
    type: 'filesystem'
  }
}
  1. 减少解析范围
module.exports = {
  resolve: {
    modules: [path.resolve(__dirname, 'src'), 'node_modules']
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        include: path.resolve(__dirname, 'src'),
        exclude: /node_modules/
      }
    ]
  }
}
  1. 使用多进程
const TerserPlugin = require('terser-webpack-plugin')
 
module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: true
      })
    ]
  }
}
  1. 使用 DllPlugin 参考 性能优化 章节。

内存溢出

问题:JavaScript heap out of memory

错误信息

FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory

解决方案

  1. 增加 Node.js 内存限制
node --max-old-space-size=4096 node_modules/.bin/webpack
  1. 修改 package.json
{
  "scripts": {
    "build": "node --max-old-space-size=4096 node_modules/.bin/webpack"
  }
}
  1. 优化配置
  • 减少入口文件
  • 使用代码分割
  • 排除不必要的文件

样式不生效

问题:CSS 样式未加载

解决方案

  1. 检查 Loader 配置顺序
// ✅ 正确顺序
use: ['style-loader', 'css-loader', 'sass-loader']
  1. 检查 sideEffects 配置
{
  "sideEffects": ["*.css", "*.scss"]
}
  1. 使用 MiniCssExtractPlugin
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
 
module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader']
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin()
  ]
}
  1. 检查 CSS Modules 配置
{
  loader: 'css-loader',
  options: {
    modules: {
      localIdentName: '[name]__[local]__[hash:base64:5]'
    }
  }
}

热更新不工作

问题:HMR 不生效

解决方案

  1. 检查 devServer 配置
module.exports = {
  devServer: {
    hot: true
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin()
  ]
}
  1. React HMR
npm install --save-dev @pmmmwh/react-refresh-webpack-plugin
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
 
module.exports = {
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        use: {
          loader: 'babel-loader',
          options: {
            plugins: ['react-refresh/babel']
          }
        }
      }
    ]
  },
  plugins: [
    new ReactRefreshWebpackPlugin()
  ]
}
  1. 检查文件监听
module.exports = {
  watchOptions: {
    ignored: /node_modules/
  }
}

打包文件过大

问题:打包后的文件体积过大

解决方案

  1. 启用代码分割
module.exports = {
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  }
}
  1. 使用 Tree Shaking
module.exports = {
  mode: 'production',
  optimization: {
    usedExports: true,
    sideEffects: false
  }
}
  1. 压缩代码
const TerserPlugin = require('terser-webpack-plugin')
 
module.exports = {
  optimization: {
    minimize: true,
    minimizer: [new TerserPlugin()]
  }
}
  1. 使用 externals
module.exports = {
  externals: {
    'react': 'React',
    'react-dom': 'ReactDOM'
  }
}
  1. 分析打包结果
npm install --save-dev webpack-bundle-analyzer
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
 
module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
}

其他常见问题

Source Map 不工作

解决方案

module.exports = {
  devtool: 'source-map'  // 或 'eval-source-map'
}

图片路径错误

解决方案

module.exports = {
  output: {
    publicPath: '/'  // 或 CDN 路径
  }
}

TypeScript 类型错误

解决方案

  1. 检查 tsconfig.json 配置
  2. 确保安装了类型定义
  3. 检查 @types 包版本

端口被占用

解决方案

module.exports = {
  devServer: {
    port: 3001  // 更换端口
  }
}

调试技巧

1. 查看详细错误信息

webpack --stats verbose

2. 使用 webpack-bundle-analyzer

npm run build -- --analyze

3. 检查配置

console.log(JSON.stringify(config, null, 2))

4. 使用 Speed Measure Plugin

const SpeedMeasurePlugin = require('speed-measure-webpack-plugin')
const smp = new SpeedMeasurePlugin()
 
module.exports = smp.wrap({
  // 配置
})

总结

  • 路径问题:检查路径、配置 alias 和 extensions
  • 依赖冲突:使用 alias 或重新安装
  • 构建速度:启用缓存、多进程、减少解析范围
  • 内存溢出:增加内存限制或优化配置
  • 样式问题:检查 Loader 顺序和 sideEffects
  • 热更新:检查配置和插件
  • 文件过大:代码分割、Tree Shaking、压缩

下一步


Webpack 问题排查 调试 常见错误