文章目录
webpack 中 chunkHash 和 contentHash 的区别

 主要从四方面来讲一下区别:1、hash的生成依据;2、影响范围;3、用途;4、限制。以及我们如何使用
- chunkHash:
 
- 生成依据:基于每个 chunk 的内容生成哈希值。
 - 影响范围:同一个 chunk 内的所有模块发生变化时,chunkhash 会重新生成。
 - 用途:适合用来区分不同的打包文件,比如入口文件(main.js)和依赖模块文件(vendor.js)。
 - 限制:如果 chunk 中的非代码部分(比如引入的样式或其他模块)变化了,chunkhash 也会变化,不够精细。
 
output: {
  filename: '[name].[chunkhash].js',
},
 
场景问题:
 假设你修改了项目中的 CSS 文件,但由于 CSS 和 JS 打包在同一个 chunk 中,chunkhash 会因为 CSS 的变化而导致 JS 文件的哈希值也发生变化,这可能会导致缓存失效。
- contenthash
 
- 生成依据:基于具体文件内容生成哈希值。
 - 影响范围:仅在内容本身发生变化时,contenthash 才会重新生成。
 - 用途:适用于精细化缓存管理,特别是 CSS 和 JS 文件分离的场景。
 - 优势:修改 CSS 不会影响 JS 文件的哈希值,反之亦然。
 
示例:
output: {
  filename: '[name].[contenthash].js',
},
 
场景优点:
 假设你对 CSS 文件进行了修改,只有 CSS 文件的哈希值会更新,而 JS 文件的哈希值不会变动,这样用户浏览器可以继续使用缓存的 JS 文件。
如何选择:
- 开发模式:一般直接使用hash(全局简单哈希值,生成快)
 - 生产模式: 
  
- 使用chunkhash 来管理js文件缓存
 - 使用contenthash来管理css和其他静态文件的缓存
 - 借助 MiniCssExtractPlugin将css抽离,并使用contenthash防止js和css哈希混淆
 
 
Webpack 配置参考:
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
  output: {
    filename: '[name].[chunkhash].js', // JS 使用 chunkhash
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '[name].[contenthash].css', // CSS 使用 contenthash
    }),
  ],
};
 
loader和plugin的区别?
webpack 处理 image 是用哪个 loader,限制 image 大小的是…;
在 Webpack 中,处理 图片(image) 通常使用 url-loader 或 file-loader,结合 asset 模式(Webpack 5 引入的新特性)更为常见。
- 图片处理 Loader
 
- url-loader 
  
- 用于将图片转为 Base64 编码的 Data URL 形式,嵌入到 JavaScript 文件中。
 - 优点:小图片可内嵌,减少 HTTP 请求。
 - 限制:较大的图片内嵌会增加打包文件体积。
 
 - file-loader 
  
- 用于将图片作为 文件输出,并返回对应的路径。
 - 优点:适合较大的图片文件,不会嵌入到 JS 中。
 - 限制:需要额外的 HTTP 请求。
 
 
- Webpack 5 的 asset 模式
 
- 取代了传统的 url-loader 和 file-loader,统一处理静态资源。
 - 提供两种自动选择方式: 
  
- asset/resource:类似 file-loader,将文件输出为单独的文件。
 - asset/inline:类似 url-loader,将文件内嵌为 Base64。
 - asset:根据文件大小自动选择 resource 或 inline(默认阈值 8 KB)。
 - asset/source:将文件内容作为字符串导入。
 
 
- 限制图片大小的配置
url-loader 示例
通过 limit 参数限制图片大小,超出限制的会作为文件处理,否则转为 Base64。 
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|jpeg|gif|svg)$/i, // 处理图片文件
        use: [
          {
            loader: 'url-loader',
            options: {
              limit: 8192, // 限制大小为 8 KB,小于此值会转为 Base64
              name: '[name].[hash:8].[ext]', // 输出文件名
              outputPath: 'images', // 输出到 images 文件夹
            },
          },
        ],
      },
    ],
  },
};
 
Webpack 5 的 asset 模式
 设置 asset 模式时,限制图片大小的方式是通过 parser.dataUrlCondition.maxSize 指定阈值(单位字节,默认 8 KB)。
module.exports = {
  module: {
    rules: [
      {
        test: /\.(png|jpg|jpeg|gif|svg)$/i, // 处理图片
        type: 'asset', // 根据大小自动选择 inline 或 resource
        parser: {
          dataUrlCondition: {
            maxSize: 8192, // 超过 8 KB 则单独打包成文件
          },
        },
        generator: {
          filename: 'images/[name].[hash:8][ext]', // 输出路径和文件名
        },
      },
    ],
  },
};
 
- 推荐使用
在 Webpack 5 中,建议直接使用 asset 模式,这样无需额外安装 url-loader 或 file-loader,而且配置更加简单灵活。
如果你有特殊的需求(比如区分非常小或非常大的文件处理方式),可以手动指定 type 为 asset/inline 或 asset/resource。 
webpack 如何优化打包速度
- 减少文件搜索范围
 
- 优化 resolve 配置:
限制模块解析路径,减少解析时间。 
resolve: {
  extensions: ['.js', '.jsx', '.json'], // 文件后缀范围
  alias: { '@': path.resolve(__dirname, 'src') }, // 路径别名
  modules: [path.resolve('node_modules')], // 仅在指定目录搜索模块
}
 
- 指定 include 和 exclude:
在 loader 中明确指定需要处理的范围。 
module: {
  rules: [
    {
      test: /\.js$/,
      loader: 'babel-loader',
      include: path.resolve(__dirname, 'src'),
      exclude: /node_modules/,
    },
  ],
},
 
- 缓存机制
开启持久化缓存:
Webpack 5 原生支持持久化缓存,能显著提升构建速度。 
cache: {
  type: 'filesystem', // 使用文件缓存
},
 
Babel-loader 缓存:
 配置 cacheDirectory 将 Babel 编译结果缓存到文件系统。
module: {
  rules: [
    {
      test: /\.js$/,
      loader: 'babel-loader',
      options: {
        cacheDirectory: true,
      },
    },
  ],
},
 
- 多进程/多实例打包
 
- thread-loader:
开启多线程处理,适合较重的 loader。 
module: {
  rules: [
    {
      test: /\.js$/,
      use: ['thread-loader', 'babel-loader'],
    },
  ],
},
 
- 压缩优化
TerserPlugin:
配置并行压缩,默认在生产模式下启用。 
optimization: {
  minimize: true,
  minimizer: [
    new TerserPlugin({
      parallel: true, // 多线程压缩
    }),
  ],
},
 
- 减少文件体积
 
- 按需加载:
通过动态 import 实现代码分割,减少初始加载文件的体积。 - Tree Shaking:
移除无用代码,确保使用 ES Module。 
复制代码
optimization: {
  usedExports: true, // 标记未使用的导出
},
 
- 开发模式下的优化
使用 source-map 的更快模式:
如 eval-source-map 或 cheap-module-source-map。 
devtool: 'cheap-module-source-map',
 
使用 webpack-dev-server 提升本地开发效率:
devServer: {
  hot: true, // 热模块替换
},
 
- 减少构建体积
使用外部依赖 (externals):
将第三方库从打包中排除,通过 CDN 引入。 
externals: {
  react: 'React',
  'react-dom': 'ReactDOM',
},
 
- 减少依赖包:
删除无用的依赖。
使用体积更小的包(如 lodash-es 替代 lodash)。 
- 分析和监控
使用打包分析工具:
如 webpack-bundle-analyzer,找到体积较大的模块优化。 
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
plugins: [
  new BundleAnalyzerPlugin(),
]










