ztoben / assets-webpack-plugin

Webpack plugin that emits a json file with assets paths
https://www.npmjs.com/package/assets-webpack-plugin
MIT License
958 stars 104 forks source link

compression-webpack-plugin output is no longer added to assets #443

Open JosephBrooksbank opened 2 years ago

JosephBrooksbank commented 2 years ago

Describe the bug On the previous version:

webpack: 4.46.0
assets-webpack-plugin: 5.1.1
compression-webpack-plugin: 5.0.0

The output gzips from compression-webpack-plugin were added to assets.json, ex:

{
  "main": {
    "js": "/js/main.4f396d722f90d5f9f22f.js"
  },
  "vendors~main": {
    "js": "/js/vendors~main.21fa04b648dd8603bee4.js"
  },
  "": {
    "png": [
      "/assets/img/arrow-down.png",
      "/assets/img/arrow-up.png",
      "/assets/img/fish.png"
    ],
    "svg": [
      "/assets/img/logo_v2.svg",
      "/assets/img/logo.svg"
    ],
    "gz": [
      "/assets/img/logo_v2.svg.gz",
      "/assets/img/logo.svg.gz",
      "/js/main.4f396d722f90d5f9f22f.js.gz",
      "/js/main.4f396d722f90d5f9f22f.js.map.gz",
      "/js/vendors~main.21fa04b648dd8603bee4.js.gz",
      "/js/vendors~main.21fa04b648dd8603bee4.js.map.gz"
    ]
  }
}

However, after updating to

webpack: ^5.0.0

The gzip portions no longer appear, at least on assets-webpack-plugin versions 5.1.1, 7.0.0, and 7.1.0 (tested). The zips are still being generated, they just aren't being recorded in the assets.json.

Expected behavior That the zipped bundles and files will appear in assets.json

Webpack Config The webpack configuration you are using when seeing the bug.

const path = require('path');
const AssetsPlugin = require('assets-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin')

module.exports = (env, argv) => {
    const entryPoint = argv.mode === 'development' ? './src/app/devIndex.tsx' : './src/app/index.tsx';
    return {
        devtool: 'cheap-module-source-map',
        target: 'node',
        entry: entryPoint,
        plugins: [
            new CompressionPlugin({
                filename: '[path].gz[query]',
                algorithm: "gzip"
            }),
            new CleanWebpackPlugin({
                cleanOnceBeforeBuildPatterns: ['./js/*']
            }),
            new AssetsPlugin({
                filename: 'webpack.assets.json',
                path: __dirname,
                prettyPrint: true
            })
        ],
        optimization: {
            splitChunks: {
                chunks: 'all',
            },
        },
        output: {
            filename: 'js/[name].[contenthash].js',
            path: path.resolve(__dirname, 'wwwroot'),
            publicPath: '/'
        },
        resolve: {
            // Add `.ts` and `.tsx` as a resolvable extension.
            extensions: [".ts", ".tsx", ".js"],
            alias: {
                App: path.resolve(__dirname, 'src/app/'),
                Components: path.resolve(__dirname, 'src/components/'),
                Models: path.resolve(__dirname, 'src/models/'),
                Redux: path.resolve(__dirname, 'src/redux/'),
                Resources: path.resolve(__dirname, 'src/resources/'),
                Screens: path.resolve(__dirname, 'src/screens/'),
                Services: path.resolve(__dirname, 'src/services/'),
                Shell: path.resolve(__dirname, 'src/shell/'),
                globalize$: path.resolve(__dirname, "node_modules/globalize/dist/globalize.js"),
                globalize: path.resolve(__dirname, "node_modules/globalize/dist/globalize"),
                }
        },
        module: {
            rules: [
                // all files with a `.ts` or `.tsx` extension will be handled by `ts-loader`
                {
                    test: /\.tsx?$/,
                    use: [
                        {
                            loader: "ts-loader",
                            options: {
                            }
                        }
                    ]
                },
                {
                    test: /\.(s*)css$/,
                    use: [
                        {
                            loader: 'style-loader',
                            options: {
                            }
                        },
                        {
                            loader: 'css-loader',
                            options: {
                            }
                        },
                        {
                            loader: 'sass-loader',
                            options: {
                            }
                        }
                    ]
                },
                // file loader will take the following extensions and put them in assets/img/
                // TODO: This will create a duplicate of the open-iconic.svg file
                {
                    test: /\.(png|svg|jpg|gif)$/,
                    use: [
                        {
                            loader: 'file-loader',
                            options: {
                                name: '[name].[ext]',
                                outputPath: 'assets/img'
                            }
                        }
                    ]
                },
                {
                    test: /\.tsx?$/,
                    use: [
                        {
                            loader: 'eslint-loader',
                            options: {
                                fix: true
                            }
                        }
                    ]
                },
                {
                    test: /\.(ttf|woff|woff2)$/,
                    use: [
                        {
                            loader: 'url-loader?name=[name].[ext]'
                        }
                    ]
                }
            ]
        }
    };
};

Desktop (please complete the following information):

nnmn commented 2 years ago

I am having the same problem while doing a Node upgrade to 16. As far as I can see the problem is that the plugin registers itself with the legacy compiler.hooks.emit.tapAsync(plugin, emitPlugin); and is run with the legacy plugins. The compression plugin uses the new compiler.hooks.thisCompilation.tap(pluginName, compilation => {compilation.hooks.processAssets.tapPromise({ name: pluginName, stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_OPTIMIZE_TRANSFER, additionalAssets: true } ... So the fix would probably be running the plugin in processAssets/PROCESS_ASSETS_STAGE_REPORT and adding a parameter to choose between new and legacy mode?

MitchTalmadge commented 2 years ago

Can confirm this problem, latest everything.

mlshohet commented 1 year ago

Same here. The strange part is if the "delete original assets" option is set in the compression plugin, it works. It only lists either the original assets, or the zipped assets if the original assets are set to be deleted. But not both. So if you're ok with just having the zipped assets, this is a viable workaround.

This is probably the same issue (so I didn't want to start one,) but it also clashes with the brotli plugin (https://www.npmjs.com/package/brotli-webpack-plugin) and doesn't list anything that is generated by it.

Love this plugin though! Such great work!