2

我已经在构建一个工作网络应用程序,其配置已停用 gzip 压缩。

我使用HtmlWebpackPlugin将 Vue 的东西和生成的块(js 和 css)注入到 mainindex.html中。

这些块是由splitChunksWebpack 4 的指令创建的。

我现在想要的是激活CompressionWebpackPlugin以使我的大输出文件更小。

如果没有块,压缩插件会做得很好。它为每个块创建一个*.js.gz文件,但是,它不会将每个块中的引用更新到其他块。

因此,浏览器将无法找到所有需要的文件。

例如,index.html有一个或两个对chunk1.js.gzand的引用chunk2.js.gz,但在chunk1and内部chunk2有许多对其他块的引用,这些引用是找不到的,因为引用有结尾.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
4

1 回答 1

0

关于为什么存在压缩插件的具体问题,答案是它可以在您的服务器端创建压缩包。

对 JavaScript 的请求是从带有普通 JS 扩展的客户端浏览器发出的。但是,浏览器请求中发送的标头包括它可以接受的响应类型。查看该accept-encoding字段,通常您会在那里看到 gzip 和 Brotli。

您的服务器应该会收到对 JS 文件的请求,但那里的代码应该在标头中查看以找出作为响应的格式。您的服务器通常应该返回以前使用客户端可以处理的压缩插件压缩的内容。

于 2021-04-22T11:53:11.750 回答