0

I'm trying to get Webpack to minify my Javascript code when it's being run through Yarn. I believe I've got everything setup correctly, however the Javascript just isn't being minified.

I've built a docker box to reproduce this problem: https://github.com/Danack/ReactTest (which probably doesn't work on Windows)

I've tested that the Uglify code is working my minifying a test file by manually calling Uglify.minify(), and it is.

This is my Webpack config file:

var webpack = require("webpack");
var path = require("path");

// This is just to test whether uglify is working.
var UglifyJS = require('uglify-js');
var fs = require('fs');
var result = UglifyJS.minify('./src/compress_test.js', {
  mangle: true,
  compress: {
    sequences: true,
    dead_code: true,
    conditionals: true,
    booleans: true,
    unused: true,
    if_return: true,
    join_vars: true,
    drop_console: true
  }
});
fs.writeFileSync('./uglify_test/manual.min.js', result.code);

module.exports = {

  entry: "./src/compress_test.js",
  devtool: "source-map",

  output: {
    path: path.resolve('./uglify_test'),
    filename: "[name].js"
  },

  plugins: [
    new webpack.optimize.UglifyJsPlugin({
      mangle: true,
      compress: {
        sequences: true,
        dead_code: true,
        conditionals: true,
        booleans: true,
        unused: true,
        if_return: true,
        join_vars: true,
        drop_console: true
      }
    })
  ]
};

To build project webpack -d --colors --watch --config ./webpack.config.js or npm run dev:build

I setup a simple Javascript file that has long variable names to make it easy to see if the JS is being minified or no.

// compress_test.js
function really_long_test_function_name(some_really_long_param_name_1, some_really_long_param_name_2) {


  var foo_really_long_var_name_1 = some_really_long_param_name_1 + "asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd";
  var foo_really_long_var_name_2 = some_really_long_param_name_2 + "asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd";

  var foo_really_long_var_name_3 = foo_really_long_var_name_1 + foo_really_long_var_name_2;
  var foo_really_long_var_name_4 = foo_really_long_var_name_1 + foo_really_long_var_name_3;
  var foo_really_long_var_name_5 = foo_really_long_var_name_1 + foo_really_long_var_name_4;
  var foo_really_long_var_name_6 = foo_really_long_var_name_1 + foo_really_long_var_name_5;
  var foo_really_long_var_name_7 = foo_really_long_var_name_1 + foo_really_long_var_name_6;
  var foo_really_long_var_name_8 = foo_really_long_var_name_1 + foo_really_long_var_name_7;
  var foo_really_long_var_name_9 = foo_really_long_var_name_1 + foo_really_long_var_name_8;


  return foo_really_long_var_name_9.length;
}

The javascript produced by calling Uglify manually, is nicely minified.

// manual.min.js
function really_long_test_function_name(a,p){var d=a+"asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd";return(d+(d+(d+(d+(d+(d+(d+(p+"asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd")))))))).length}

The built javascript output of Webpack isn't:

!function(l){function _(n){if(a[n])return a[n].exports;var o=a[n]={i:n,l:!1,exports:{}};return l[n].call(o.exports,o,o.exports,_),o.l=!0,o.exports}var a={};_.m=l,_.c=a,_.i=function(l){return l},_.d=function(l,a,n){_.o(l,a)||Object.defineProperty(l,a,{configurable:!1,enumerable:!0,get:n})},_.n=function(l){var a=l&&l.__esModule?function(){return l.default}:function(){return l};return _.d(a,"a",a),a},_.o=function(l,_){return Object.prototype.hasOwnProperty.call(l,_)},_.p="",_(_.s=0)}([/*!******************************!*\
  !*** ./src/compress_test.js ***!
  \******************************/
function(module,exports){eval('\n\nfunction really_long_test_function_name(some_really_long_param_name_1, some_really_long_param_name_2) {\n\n\n  var foo_really_long_var_name_1 = some_really_long_param_name_1 + "asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd";\n  var foo_really_long_var_name_2 = some_really_long_param_name_2 + "asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd";\n\n  var foo_really_long_var_name_3 = foo_really_long_var_name_1 + foo_really_long_var_name_2;\n  var foo_really_long_var_name_4 = foo_really_long_var_name_1 + foo_really_long_var_name_3;\n  var foo_really_long_var_name_5 = foo_really_long_var_name_1 + foo_really_long_var_name_4;\n  var foo_really_long_var_name_6 = foo_really_long_var_name_1 + foo_really_long_var_name_5;\n  var foo_really_long_var_name_7 = foo_really_long_var_name_1 + foo_really_long_var_name_6;\n  var foo_really_long_var_name_8 = foo_really_long_var_name_1 + foo_really_long_var_name_7;\n  var foo_really_long_var_name_9 = foo_really_long_var_name_1 + foo_really_long_var_name_8;\n\n\n  return foo_really_long_var_name_9.length;\n}\n\n\n\n\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjoz **** SOURCE_MAPPING_NOT_SHOWN_HERE***')}]);

The long variable names are still there.

What do I need to do to make webpack actually minify the Javascript that it outputs?

In case it matters, I'm using Yarn 0.23.4 and Node 7.10.0

5 Answers 5

3
+300

You use -d. It is shortcut for --debug --devtool eval-cheap-module-source-map --output-pathinfo

This part --devtool eval-cheap-module-source-map rewrites your devtool in config and leave

original source (lines only)

Sign up to request clarification or add additional context in comments.

Comments

1

if you are using the newer version of uglifyjs-webpack-plugin then you can use the code plugin setting like below and it should be working . there are a couple of minor changes here with respect to the uglify options :

new UglifyJsPlugin({ 
            uglifyOptions: {
                mangle: true,
                output: {
                    comments: false
                }
            },
            sourceMap: true,
            exclude: [/\.min\.js$/gi]
       })

Comments

0

You don't need to manually include uglifyjs as it comes bundled with webpack.

You should only really need to minify when building for production, the minification will be applied automatically when you run webpack in production mode, i.e.:

webpack -p

or

webpack --optimize-minimize --define process.env.NODE_ENV="'production'"

For more details, checkout this website: https://webpack.js.org/guides/production-build/

2 Comments

If I use the -p flag, without removing the UglifyJsPlugin, I get an error which apparently is a common thing when Uglify is being applied twice. If I remove the plugin, and leave the -p flag, then it looks like no minification has been done.
btw I've also tried using new webpack.DefinePlugin({'process.env': {'NODE_ENV': JSON.stringify('production')}}) in the webpack config file for an explicit production config. That doesn't seem to make much difference either.
0

It looks like you are trying to use uglify with the watch flag, which is intended to be used in development.

As you can see, it's wrapping your code in an eval statement and multiple wrappers that is messing with the uglification process. I also suspects it might purposely keeps the source unmangled for debugging purposes.

From your Dockerfile, you're running this command from your package, that makes me think that you are trying to use webpack as both your bundler and file server on production, which is not what it should be used for.

By taking your exact configuration and files, I had no problem generating the output minified file by simply declaring a script that look like:

"prod:build": "webpack"

Since you have dead_code: true and drop_console: true, you might have to set these to false with your current code, since the method is never called, what I did is call it with console.log and set drop_console to false

console.log(really_long_test_function_name('a', 'b'))

The result of the build will look like

!function(o){function n(t){if(r[t])return r[t].exports;var e=r[t]={i:t,l:!1,exports:{}};return o[t].call(e.exports,e,e.exports,n),e.l=!0,e.exports}var r={};n.m=o,n.c=r,n.i=function(o){return o},n.d=function(o,r,t){n.o(o,r)||Object.defineProperty(o,r,{configurable:!1,enumerable:!0,get:t})},n.n=function(o){var r=o&&o.__esModule?function(){return o.default}:function(){return o};return n.d(r,"a",r),r},n.o=function(o,n){return Object.prototype.hasOwnProperty.call(o,n)},n.p="",n(n.s=0)}([function(o,n){console.log(function(o,n){var r=o+"asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd";return(r+(r+(r+(r+(r+(r+(r+(n+"asdjpajdpoadpsapodjpasojdpoajpdoaspdpasjd")))))))).length}("a","b"))}]);%

Running the webpack binary will take the webpack.config.js automatically. Also, don't need to specify mangle: true for the plugin, as it is already the default value.


To resume, do the normal production build with minification without the -watch option, and install something like nginx in your docker to serve your files in production.

2 Comments

" that makes me think that you are trying to use webpack as both your bundler and file server on production" - no, the compiled files will actually be served as part of a PHP application. This stuff is just for dev, and is more for easy repro, than the actual setup. Can you confirm that you were running the webpack through the docker box? Unfortunately I can't test "prod:build" until I get back to a non-windows machine tomorrow.
If this is for dev, it doesn't make sense for me to activate the uglify anyway, you need to be able to debug easily, and mangling your methods will not be helpful. If the compiled files will be served by PHP that's good then. I haven't done it through the docker box, but there should be absolutely no problem to run prod:build, let me know ;)
-1

In your code where you call the options, add:

new webpack.optimize.UglifyJsPlugin({
      mangle: true, { keep_fnames: false, screw_ie8: true },
      compress: true, { keep_fnames: false, screw_ie8: true }
})

I do not know the options you're trying to set? Are you sure they are webpack uglify options? Anyway, hope this helps.

EDIT:

Try this:

const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');

Check if that lib is in that directory to be sure.

new UglifyJsPlugin({
        beautify: false,
        comments: false,
        ...
      }),

This will call upon your the original Uglify plugin more directly... Try your previous set options on this.

9 Comments

"I do not know the options you're trying to set?" I was trying stuff at random, but the are valid options: lisperator.net/uglifyjs/compress The JS you posted doesn't appear to be valid.
You're not using that... You're using the "webpack.optimize.UglifyJsPlugin". They are not all the same... Did you try my suggestion?
"Did you try my suggestion?" - yes. What you suggested gives a syntax error as it's not valid Javascript.
btw I thought the UglifyJsPlugin for webpack is just a wrapper for that library, as it's listed in it's dependencies: github.com/webpack-contrib/uglifyjs-webpack-plugin/blob/master/…
A wrapper can do anything to the syntax of the origin module... Look in the source of the webpack-plugin... If you wan't to be persistent in those options and not try anything else, then I don't think anyone can help you really? Because then what is your question?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.