webpack常用的一些优化

493 阅读2分钟

Webpack是现在主流的功能强大的模块化打包工具,在使用Webpack时,如果不注意性能优化,有非常大的可能会产生性能问题,性能问题主要分为开发时打包构建速度慢、开发调试时的重复性工作、以及输出文件质量不高等,因此性能优化也主要从这些方面来分析。

1.开发环境优化

1.1 resolve.modules

告诉webpack在那个文件夹下面去找第三方模块,避免了层层的查找

resolve:{
    modules:[path.resolve(__dirname,'node_modules')]
}

1.2 resolve.alias

对一些第三方比较打的库,指定其文件夹位置,避免了层层的查找

resolve:{
    alias:{
       'vue':patch.resolve(__dirname, './node_modules/vue/dist/vue.min.js'),
       'react':patch.resolve(__dirname, './node_modules/react/dist/react.min.js') 
    }
}

1.3 配置loader时,通过test、exclude、include缩小搜索范围

1.4 开启happypack多线程解析

我一般在解析js文件的时候会使用

module:{
    rules:[
        {
            test: /(\.js|\.jsx)$/,
            exclude: resolve(__dirname, 'node_modules'),
            use: ['happypack/loader?id=babel'],
        },
    ]
},
plugins:[
    new happypack({
        id:"babel",
        loaders:[
            {loader:'babel-loader?cacheDirectory=true'}
        ]
    })
]

1.5 开启paralleUgilifyPlugin多线程压缩js文件

new ParallelUglifyPlugin({
            uglifyJS: {
                output: {
                    //去除空格
                    beautify: false,
                    //去除注释
                    comments: false
                },
                compress: {
                    //删除所有的console
                    drop_console: false
                }
            }
}),

1.6 开启热模块替换HMR

模块热替换不刷新整个网页而只重新编译发生变化的模块,并用新模块替换老模块

/**
* 启用webpack内置的webpack插件(开启HMR)
*/
 new webpack.HotModuleReplacementPlugin(),
devServer:{
    hot:true
}

1.7 resolve.extensions减少文件查找

resolve.extensions:['.js','.json']

后缀名列表尽可能的少,使用频率高的文件后缀名放前面。

1.8 module.noParse

用了noParse的模块将不会被loaders解析,所以当我们使用的库如果太大,并且其中不包含import require、define的调用,我们就可以使用这项配置来提升性能, 让 Webpack 忽略对部分没采用模块化的文件的递归解析处理。

module.noParse=/jquery/

1.9 hard-source-webpack-plugin

hard-source-webpack-plugin为模块提供缓存,首次构建时间没有太大变化,但是第二次开始,构建时间可以大大减少。

var HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
module.exports = {
    plugins:[
        new HardSourceWebpackPlugin()
    ]
}

2.生产环境优化

2.1 单独提取css代码MiniCssExtractPlugin

{
    test:/\.css$/,
    use:[MiniCssExtractPlugin.loader,css-loader]
}
new MiniCssExtractPlugin({
    filename:'css/[name].[hash:10].css'
})

2.2压缩css OptimizeCssAssetsWebpackPlugin

new OptimizeCssAssetsWebpackPlugin()

2.3 代码分割 optimization

这个是splitChunks的默认配置

optimization: {
        splitChunks: {
            chunks: 'all',
            minSize: 30000, //块的最小大小,只有超过30k,才会进行代码分割
            maxSize: 0,
            minChunks: 1, //模块至少需要被引用1次
            maxAsyncRequests: 5, //最大打包数量
            maxInitialRequests: 3, //entry入口最大数量
            automaticNameDelimiter: '~',
            name: true,
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    priority: -10,
                    reuseExistingChunk: true
                },
                default: {
                    minChunks: 2,
                    priority: -20,
                    reuseExistingChunk: true
                }
            }
        },
        runtimeChunk: {
            name: entrypoint => `manifest.${entrypoint.name}`
        }
    }

我通常改成这样

optimization: {
        splitChunks: {
            chunks: 'all',
            cacheGroups: {
                styles: {
                    name: 'styles',
                    test: /\.(css|less|sass)$/,
                    chunks: 'all',
                    priority: 10,//优先级最高,现将css提取出来
                },
                common:{
                    name:'common',
                    chunks: 'all',
                    priority:1,
                    reuseExistingChunk:true,//应用了已经抽离的chunk,不会创建新的chunk
                },
                vendors:{
                    name:'vendors',
                    test: /[\\/]node_modules[\\/]/,
                    chunks: 'all',
                    priority:2,
                    reuseExistingChunk:true,
                }
            }
        }
    }

2.4 按需加载

import(/*webpackChunkName:"one*/'./one.js').then(data=>{
    console.log(data);
})

2.5 CDN引入第三方包

<body>
    <div id="app"></div>
    <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
</body>
externals:{
    jquery:"jQuery",//告诉webpack哪些第三方包不参与打包,优化首屏加载速度
}

2.6 source-map

我的用法:

devtool: process.env.NODE_ENV == 'development' ? 'eval-source-map' : 'cheap-module-source-map',

2.7 开启gzip压缩

gizp压缩是一种http请求优化方式,前端配置gzip压缩,并且服务端使用nginx开启gzip,用来减小网络传输的流量大小。

const CompressionWebpackPlugin = require('compression-webpack-plugin') 

plugins: [ 
    new CompressionWebpackPlugin()
]

2.8 Tree Shaking剔除无用代码