how to minify js files in order via grunt-contrib-uglify? how to minify js files in order via grunt-contrib-uglify? node.js node.js

how to minify js files in order via grunt-contrib-uglify?


Good questions!

1) Uglify will reorder the functions in the destination file so that function definitions are on top and function execution on bottom but it seems that it will preserve the order of the function executions.

This means that the function jQuery runs to define its global functions will be put first if you make sure jQuery is mentioned first in Uglify's config in the Gruntfile.

I use this config:

uglify: {    options: {        sourceMap: true    },    build: {        files: {            'public/all.min.js': ['public/js/vendor/jquery-1.10.2.min.js', 'public/js/*.js'],        }    }}

2) I don't think there is one definite way to accomplish this. It depends on what web framework, templating framework and what kind of requirements you have. I use express + jade and in my main jade layout I have:

if process.env.NODE_ENV === 'production'  script(src='/all.min.js')else  script(src='/js/vendor/jquery-1.10.2.min.js')  script(src='/js/someScript.js')  script(src='/js/otherScript.js')

In my package.json I have:

"scripts": {  "postinstall": "grunt"},

This means that when I run npm install on deploy (on Heroku) grunt is run to minify/concat files and when the app is started with NODE_ENV=production the minified client side javascript is used. Locally I get served the original client side javascripts for easy debugging.

The two downsides are:

  • I have to keep the two lists of script files in sync (in the Gruntfile and in the layout.js) I solve this by using *.js in the Gruntfile but this may not suite everyone. You could put the list of javascripts in the Gruntfile and create a jade-template from this but it seems overkill for most projects.
  • If you don't trust your Grunt config you basically have to test running the application using NODE_ENV=production locally to verify that the minification worked the way you intended.


This can be done using the following Grunt tasks:

  1. https://github.com/gruntjs/grunt-contrib-concat concatenatesfiles
  2. https://github.com/gruntjs/grunt-contrib-uglify minifiesconcatenated files

EDIT

I usually run all my files through a Grunt concatenation task using grunt-contrib-concat. Then I have another task to uglify the concatenated file using grunt-contrib-uglify.


You're probably not going to like this, but the best way is to define your js source files as AMD modules and use Requirejs to manage the order in which they load. The grunt-contrib-requirejs task will recurse your dependency tree and concatenate the js files in the necessary order into one big js file. You will then use uglify (actually r.js has uglify built-in) to minify the big file.

https://github.com/danheberden/yeoman-generator-requirejs has a good example gruntfile and template js files to work from.

EDIT

I've recently started using CommonJS modules instead of AMD since it's much closer to the ES6 module spec. You can achieve the same results (1 big complied+concatenated js file) by running commonjs modules through Browserify. There are plugins for both grunt and gulp to manage the task for you.

EDIT

I'd like to add that if your site is written using ES6 that Rollup is the best new concatenating package. In addition to bundling your files, it will also perform tree shaking, removing parts of libraries you use if included via an import statement. This reduces your codebase to just what you need without the bloat of code you'll never use.