MST

星途 面试题库

面试题:Webpack 多入口项目中如何避免公共模块重复打包

在一个 Webpack 构建的多入口项目里,存在多个页面入口,且有一些公共的模块(如通用的工具函数库、样式文件等)。请详细说明你会采取哪些措施来避免这些公共模块在每个入口打包时重复打包,包括使用 CommonsChunkPlugin(或其替代方案)的配置思路、插件的原理,以及如何根据项目实际情况进行优化。
15.3万 热度难度
前端开发Webpack

知识考点

AI 面试

面试题答案

一键面试

避免公共模块重复打包的措施

  1. 使用 CommonsChunkPlugin 及其替代方案
    • Webpack4 及之前:使用 CommonsChunkPlugin
      • 配置思路:在 webpack.config.js 中,例如对于多入口配置如下:
const webpack = require('webpack');
module.exports = {
    entry: {
        page1: './src/page1.js',
        page2: './src/page2.js'
    },
    output: {
        path: __dirname + '/dist',
        filename: '[name].js'
    },
    plugins: [
        new webpack.optimize.CommonsChunkPlugin({
            name: 'commons', // 抽取出来的公共模块的名称
            chunks: ['page1', 'page2'], // 从哪些入口chunk中抽取公共模块
            minChunks: 2 // 公共模块至少被引用的次数,这里表示至少被两个入口chunk引用
        })
    ]
};
  • Webpack5CommonsChunkPlugin 已被移除,使用 splitChunks 替代。
    • 配置思路:在 webpack.config.js 中的 optimization 字段下配置,如下:
module.exports = {
    entry: {
        page1: './src/page1.js',
        page2: './src/page2.js'
    },
    output: {
        path: __dirname + '/dist',
        filename: '[name].js'
    },
    optimization: {
        splitChunks: {
            chunks: 'all', // 对所有chunk进行分割
            name: 'commons', // 公共模块名称
            minSize: 30000, // 分割的模块最小大小
            minChunks: 2 // 公共模块至少被引用的次数
        }
    }
};
  1. 插件原理
    • CommonsChunkPlugin:它通过分析入口chunk的依赖关系树,找出多个chunk中重复引用的模块,并将这些模块提取出来放到一个单独的chunk中。这样在打包时,公共模块只会被打包一次,而不是在每个入口chunk中重复打包。
    • splitChunkssplitChunks 同样是基于分析chunk之间的依赖关系,将符合条件(如 minSizeminChunks 等设定)的公共模块进行拆分并提取到单独的chunk中。它更加灵活和强大,不仅可以处理入口chunk之间的公共模块,还可以对异步chunk(如动态导入的模块)进行公共模块拆分。
  2. 根据项目实际情况优化
    • 公共模块大小:如果公共模块较小,可以适当降低 minSize 的值(在 splitChunks 中)或增加 minChunks 的值,避免过多小的公共模块文件产生,减少请求数。例如,如果项目中公共模块大多在 10 - 20KB 左右,可以将 minSize 设为 10000(10KB)。
    • 动态导入模块:对于项目中使用动态导入(import())的模块,如果这些模块之间有公共部分,可以通过 splitChunkscacheGroups 配置,对异步chunk进行更细粒度的公共模块拆分。比如:
optimization: {
    splitChunks: {
        cacheGroups: {
            asyncCommons: {
                name: 'async - commons',
                chunks: 'async',
                minChunks: 2
            }
        }
    }
}
  • 第三方库分离:对于项目中使用的第三方库(如 lodashreact 等),可以单独配置一个 cacheGroup 将它们提取到一个单独的文件中,实现长期缓存。例如:
optimization: {
    splitChunks: {
        cacheGroups: {
            vendor: {
                name:'vendor',
                test: /[\\/]node_modules[\\/]/,
                chunks: 'all'
            }
        }
    }
}