Reputation: 25701
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
Upvotes: 0
Views: 12039
Reputation: 235
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]
})
Upvotes: 1
Reputation: 5990
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
Upvotes: 3
Reputation: 35796
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.
Upvotes: 0
Reputation: 34
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/
Upvotes: 0
Reputation: 1018
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.
Upvotes: -1