webpack-contrib / terser-webpack-plugin

Terser Plugin
MIT License
1.95k stars 157 forks source link

Allow a post-minify task. #298

Closed VictorioBerra closed 4 years ago

VictorioBerra commented 4 years ago

Feature Proposal

Webpack.Config

module.exports = {
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        // Can be async
        minify: (file, sourceMap) => {
          const extractedComments = [];

          // Custom logic for extract comments

          const { map, code, extractedComments } = require('terser-webpack-plugin/minify') // CANT DO THIS!!!!
            .minify(file);

         const finalCode = "/* eslint-disable */" + code ;

          return { map, finalCode, extractedComments };
        },
      }),
    ],
  },
};

Feature Use Case

I need to add a header to my code. The easiest way to do this is to override the minify function, however, using terser's minify after I do that is a huge pain. Its easier to use uglify in the minify function but that negates the whole point of using terser IMO.

I want to leverage the minify stuff already built into terser-webpack-plugin but I can not because it is not easily exposed.

alexander-akait commented 4 years ago

Sorry it is out of scope terser-webpack-plugin, you can create a custom plugin to adding custom code above generated code, also please look at https://webpack.js.org/plugins/banner-plugin/

VictorioBerra commented 4 years ago

Thanks. But Banner does not work for me. It wraps everything in a comment, and if you disable this (raw) then the minifier/uglifier/terserfier will just rip out whatever comment you try and put in manually like my eslint example above. So I am attempting to manually add my comment to the minified code.

On Tue, Aug 18, 2020 at 12:19 PM Evilebot Tnawi notifications@github.com wrote:

Sorry it is out of scope terser-webpack-plugin, you can create a custom plugin to adding custom code above generated code, also please look at https://webpack.js.org/plugins/banner-plugin/

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/webpack-contrib/terser-webpack-plugin/issues/298#issuecomment-675607896, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAWMN22LEDQTGUU72N6GPHLSBKZ2LANCNFSM4QDYZW3A .

-- Victorio Berra toryberra@gmail.com 636-328-7110

alexander-akait commented 4 years ago

You can use https://github.com/webpack-contrib/terser-webpack-plugin#extractcomments and ignore this comment

VictorioBerra commented 4 years ago

@evilebottnawi That ended up working for me, thanks. Getting some other issues now though I may make a new issue shortly.

alexander-akait commented 4 years ago

@VictorioBerra feel free to open issues

lilzipperoni commented 4 years ago

In case this helps anyone, in the end this is what I had to do:

Webpack.Config

const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const webpack = require('webpack');
const fs = require('fs');
const rfr = require('rfr');

const tamperMonkeyFile = fs.readFileSync(rfr.resolve('./tampermonkey.txt'), { encoding:'utf8' });
const packageVersion = rfr("./package.json").version;
const tampermonkeyFileHeader = tamperMonkeyFile.replace(/\@\@VERSION\@\@/, packageVersion);
const tampermonkeyFileHeaderLines = tampermonkeyFileHeader.split(/\n/);

module.exports = (env, argv) => {

  const isDev = argv.mode === "development";

  const pluginsArr = [
    new ForkTsCheckerWebpackPlugin()
  ];

  const optimization = {
    minimize: true,
    minimizer: []
  }

  // load plugin only in development mode
  if (!isDev) {
    optimization.minimizer.push(new TerserPlugin({
      terserOptions: {
        output: {
          comments: { 
            test: function (comment){
              if(comment) {
                return /\@/i.test(comment) || /UserScript/i.test(comment) ||  /eslint-disable/i.test(comment);
              }
            } 
          }
        },
      },
    }));
    pluginsArr.push(new webpack.BannerPlugin({
      raw: true,
      banner: tampermonkeyFileHeader
    }));
  }

  return {
    optimization: optimization,
    entry: './src/index.ts',
    devtool: isDev ? "inline-source-map" : "", // generate source code only in development mode
    module: {
      rules: [
        {
          test: /\.tsx?$/,
          exclude: /node_modules/,
          loader: 'ts-loader',
          options: {
            transpileOnly: true
          }
        },
      ],
    },
    resolve: {
      extensions: [ '.tsx', '.ts', '.js' ],
    },
    output: {
      filename: 'bundle.js',
      path: path.resolve(__dirname, 'dist'),
    },
    plugins: pluginsArr
  }
};