Webpack-cli: "webpack -p" removes banner created with webpack.BannerPlugin

Created on 5 Mar 2018  路  9Comments  路  Source: webpack/webpack-cli

Do you want to request a feature or report a bug? bug

What is the current behavior?

A configuration like: https://github.com/julmot/form-components/blob/v0.13.0/build/webpack.config.js#L85 removes the banner in production when called with webpack -p. It only works in development.

If the current behavior is a bug, please provide the steps to reproduce.

Install these requirements, then:

$ git clone https://github.com/julmot/form-components.git && cd form-components && git checkout greenkeeper/webpack-4.0.0 && npm install && npm run build

Then open dist/ and some file without .min.js.

What is the expected behavior?

Banner comments should keep persistent in production builds.

Please mention other relevant information such as the browser version, Node.js version, Operating System and programming language.

It only occurs since Webpack v4.

needs investigation

Most helpful comment

@Daiz @SavageCore

I found a solution.

npm install --save-dev uglifyjs-webpack-plugin

And a sample webpack.config.ts:

const UglifyJsPlugin = require("uglifyjs-webpack-plugin");

const METADATA = "// ==UserScript== ...";
const PRODUCTION = true; // from command-line argument etc

export default {
    // ...
    mode: PRODUCTION ? "production" : "development",
    optimization: {
        minimizer: [
            new UglifyJsPlugin({
                uglifyOptions: {
                    output: {
                        beautify: false,
                        preamble: METADATA,
                    },
                },
            }),
        ],
    },
    plugins: [
        new webpack.BannerPlugin({
            banner: METADATA,
            raw: true,
            entryOnly: true,
        }),
    ],
};

With such a configuration, UglifyJS removes the metadata block prepended by BannerPlugin from production builds, then inserts it again as a preamble.

All 9 comments

Just ran into this issue myself trying to append a block of text to the top of my bundle with BannerPlugin using raw: true. I can't really wrap my raw banner in /*! */ either because what I'm trying to inject is a UserScript Metadata Block (though seemingly even this wouldn't help because I have a license section in my banner too, wrapped in /*! */, but it disappears into the void along with everything else in the banner).

It would really be ideal if BannerPlugin was invoked after minimization, not before.

Hi @julmot, it looks like the issue is resolved. Can we close it?

@ematipico yes

@Daiz did you find a solution to keeping metadata block?

@Daiz @SavageCore

I found a solution.

npm install --save-dev uglifyjs-webpack-plugin

And a sample webpack.config.ts:

const UglifyJsPlugin = require("uglifyjs-webpack-plugin");

const METADATA = "// ==UserScript== ...";
const PRODUCTION = true; // from command-line argument etc

export default {
    // ...
    mode: PRODUCTION ? "production" : "development",
    optimization: {
        minimizer: [
            new UglifyJsPlugin({
                uglifyOptions: {
                    output: {
                        beautify: false,
                        preamble: METADATA,
                    },
                },
            }),
        ],
    },
    plugins: [
        new webpack.BannerPlugin({
            banner: METADATA,
            raw: true,
            entryOnly: true,
        }),
    ],
};

With such a configuration, UglifyJS removes the metadata block prepended by BannerPlugin from production builds, then inserts it again as a preamble.

I defined a simple webpack Banner Plugin:

// set a string as preamble

class BannerPlugin {
  constructor(options) {
    this.banner = options.banner;
  }

  apply(compiler) {
    compiler.hooks.emit.tapAsync('FileListPlugin', (compilation, callback) => {
      compilation.chunks.forEach(chunk => {
        chunk.files.forEach(filename => {
          const asset = compilation.assets[filename];
          asset._value = this.banner + asset._value; // append banner
        });
      });

      callback();
    });
  }
}

module.exports = BannerPlugin;
  • invoke
const BannerPlugin = require('./plugins/BannerPlugin');

module.exports = {
  plugins: [
    new BannerPlugin({
      banner
    }),
  ],
};

I'm trying to use uglifyjs-webpack-plugin suggested here, but it doesn't seem maintained anymore.

npm i --save-dev uglifyjs-webpack-plugin

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: [email protected]
npm ERR! Found: [email protected]
npm ERR! node_modules/webpack
npm ERR!   dev webpack@"^5.33.2" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer webpack@"^4.0.0" from [email protected]
npm ERR! node_modules/uglifyjs-webpack-plugin
npm ERR!   dev uglifyjs-webpack-plugin@"*" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See C:\Users\natob\AppData\Local\npm-cache\eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\natob\AppData\Local\npm-cache\_logs\2021-04-16T00_46_31_574Z-debug.log

It would be nice if webpack.BannerPlugin worked in production mode natively.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sam-s4s picture sam-s4s  路  5Comments

snitin315 picture snitin315  路  5Comments

billyjanitsch picture billyjanitsch  路  3Comments

fokusferit picture fokusferit  路  5Comments

Pomax picture Pomax  路  3Comments