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

talent picture talent · Dec 12, 2013 · Viewed 33.3k times · Source

I have a directory like below:

/folder/b.js
/folder/jQuery.js
/folder/a.js
/folder/sub/c.js

I want to minify all these js files in one js file in order:

jQuery.js -> a.js -> b.js -> c.js

Q:
1.How can I do it via grunt-contrib-uglify?(In fact, there are lots of files, it is impractical to specify all source filepaths individually)

2.btw, How can I get unminified files when debug and get minified single file when release and no need to change script tag in html(and how to write the script tag)?

Answer

gabrielf picture gabrielf · Mar 16, 2014

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.