I keep seeing the recommendation for making JS files ready for production to be concat then uglify.
For example here, in on of Yeoman's grunt tasks.
By default the flow is: concat -> uglifyjs.
Considering UglifyJS can do both concatenation and minification, why would you ever need both at the same time?
Thanks.
In the example you mention, which I'm quoting below, the files are first concatenated with
concat
and then uglified/minified byuglify
:The same could be achieved with:
Typically, the task
clean
would then run after tasks that write to a temporary folder (in this exampleconcat
) and delete whatever content is in that folder. Some people also like to runclean
before tasks likecompass
, to delete things like randomly named image sprites (which are newly generated every time the task runs). This would keep wheels turning even for the most paranoid.This is all a matter of preference and workflow, as is with when to run
jshint
. Some people like to run it before the compilation, others prefer to run it on compiled files.Complex projects with an incredible amount of
JavaScript
files - or with a increasingly broad number of peers & contributors, might choose to concatenate files outsideuglify
just to keep things more readable and maintainable. I think this was the reasoning behindYeoman
's choice of transformation flow.uglify
can be notoriously slow depending of the project's configuration, so there might be some small gain in concatenating it withconcat
first - but that would have to be confirmed.concat
also supports separators, whichuglify
doesn't as far asREADME.md
files are concerned.Running a basic test to see if there is a performance difference between executing
concat
and thenuglify
vs. justuglify
.package.json
Gruntfile.js
In
src
, I've put a bunch of JS files, including the uncompressed source of jQuery, copied several times, spread around into subfolders. Much more than what a normal site/app usually has.Turns out the time it takes to concat and compress all of these files is essentially the same in both scenarios.
Except when using the
sourceMap: true
option onconcat
as well (see below).On my computer:
It's worth noting that the resulting
main.min.js
is the same in both cases.Also,
uglify
automatically takes care of using the proper separator when combining the files.The only case where it does matter is when adding
sourceMap: true
to theconcat
options
.This creates a
main.js.map
file next tomain.js
, and results in:But if the production site loads only the
min
version, this option is useless.I did found a major disadvantage with using
concat
beforeuglify
.When an error occurs in one of the JS files, the
sourcemap
will link to the concatenatedmain.js
file and not the original file. Whereas whenuglify
does the whole work, it will link to the original file.Update:
We can add 2 more options to
uglify
that will link theuglify
sourcemap toconcat
sourcemap, thus handling the "disadvantage" I mentioned above.But it seems highly unnecessary.
Conclusion
I think it's safe to conclude that we can ditch
concat
for JS files if we're usinguglify
, and use it for other purposes, when needed.