如何正确压缩webpack的代码块?

3
我已经使用取消了gzip压缩的配置构建了一个工作的Web应用。
我使用HtmlWebpackPlugin来注入Vue内容和生成的片段(js和css)到主要的index.html中。
这些片段由Webpack 4的splitChunks指令创建。
现在我想启用CompressionWebpackPlugin以使我的大型输出文件更小。
如果没有块,压缩插件将可以完美地工作。它为每个块创建一个*.js.gz文件,但它不会更新每个块中对其他块的引用。
因此,浏览器将无法找到所有需要的文件。
例如,index.html有一个或两个对chunk1.js.gzchunk2.js.gz的引用,但在chunk1chunk2内部有许多对其他块的引用,这些引用无法找到,因为引用以.js结尾,而实际文件以.js.gz结尾。
我该如何正确地配置CompressionWebpackPlugin(或任何其他整个webpack设置和插件),以便它们将相应地更新文件引用?
我该如何使这完全动态,以便我甚至可以使用最小比率或最小文件大小的压缩功能?(然后某些输出块将是.js,某些块将是.js.gz,因此一些引用必须是第一个选项,一些引用必须是第二个选项)。
其他类似问题的答案表示,应该在服务器端压缩,而不是使用webpack。但是,为什么还存在压缩插件呢?
设置是Vue、Webpack(单页应用程序)、nginx、Django、Docker。
以下是我的Webpack当前配置:
'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')

const env = process.env.NODE_ENV === 'testing'
    ? require('../config/test.env')
    : require('../config/prod.env')

const webpackConfig = merge(baseWebpackConfig, {
    mode: 'production',
    module: {
        rules: utils.styleLoaders({
            sourceMap: config.build.productionSourceMap,
            extract: true,
            usePostCSS: true
        })
    },
    devtool: config.build.productionSourceMap ? config.build.devtool : false,
    output: {
        path: config.build.assetsRoot,
        filename: utils.assetsPath('js/[name].[chunkhash].js'),
        chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
    },
    plugins: [
        // extract css into its own file
        new MiniCssExtractPlugin({
            filename: utils.assetsPath('css/[name].[hash:7].css'),
            chunkFilename: utils.assetsPath('css/[id].[hash:7].css')
        }),
        // Compress extracted CSS. We are using this plugin so that possible
        // duplicated CSS from different components can be deduped.
        new OptimizeCSSPlugin({
            cssProcessorOptions: config.build.productionSourceMap
            ? { safe: true, map: { inline: false } }
            : { safe: true }
        }),
        // generate dist index.html with correct asset hash for caching.
        // you can customize output by editing /index.html
        // see https://github.com/ampedandwired/html-webpack-plugin
        new HtmlWebpackPlugin({
            filename: process.env.NODE_ENV === 'testing'
                ? 'index.html'
                : config.build.index,
            template: 'index.html',
            inject: true,
            minify: {
                removeComments: true,
                collapseWhitespace: true,
                removeAttributeQuotes: true
                // more options:
                // https://github.com/kangax/html-minifier#options-quick-reference
            },
            // necessary to consistently work with multiple chunks via CommonsChunkPlugin
            chunksSortMode: 'dependency',
            jsExtension: '.gz'
        }),
        // keep module.id stable when vender modules does not change
        new webpack.HashedModuleIdsPlugin(),
        // copy custom static assets
        new CopyWebpackPlugin([
            {
                from: path.resolve(__dirname, '../static'),
                to: config.build.assetsSubDirectory,
                ignore: ['.*']
            }
        ]),
    ],
    optimization: {
        runtimeChunk: 'single',
        splitChunks: {
            chunks: 'all',
            maxInitialRequests: Infinity,
            minSize: 0,
            cacheGroups: {
                default: false,
                vendors: false,
                vendor: {
                    test: /[\\/]node_modules[\\/]/,
                    chunks: 'all',
                    priority: 20,
                    name(module) {
                        // get the name. E.g. node_modules/packageName/not/this/part.js
                        // or node_modules/packageName
                        const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];

                        // npm package names are URL-safe, but some servers don't like @ symbols
                        return `npm.${packageName.replace('@', '')}`;
                    },
                },
                common: {
                    name: 'common',
                    minChunks: 2,
                    chunks: 'async',
                    priority: 10,
                    reuseExistingChunk: true,
                    enforce: true
                },
            },
        },
    },
})

if (config.build.productionGzip) {
    const CompressionWebpackPlugin = require('compression-webpack-plugin')

    webpackConfig.plugins.push(
        new CompressionWebpackPlugin({
            filename: '[path].gz[query]',
            algorithm: 'gzip',
            test: /\.(js|css)(\?.*)?$/i,
            //threshold: 10240,
            //minRatio: 0.8,
            deleteOriginalAssets: true,
        }),
    )
}

if (config.build.bundleAnalyzerReport) {
    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
    webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}

module.exports = webpackConfig
1个回答

0
关于“为什么存在压缩插件”的具体问题,答案是它存在于服务器端以创建压缩包。
客户端浏览器使用纯JS扩展程序发出JavaScript请求。但是,在浏览器请求中发送的标头包括其可接受的响应类型。查看accept-encoding字段,通常会看到gzip和Brotli。
您的服务器应该接收JS文件的请求,但代码应查看标头以确定要作为响应提供的格式。您的服务器通常应返回先前使用压缩插件压缩的内容,以便客户端可以处理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接