Search code examples
javascriptnode.jsmeanjs

How to minify all js and css in MEAN.JS for production environment?


I have just developed a simple MEAN.JS application. MEAN.JS provides a command grunt build that helps me to minify the js and css files located at the following folders

css: [
    'public/modules/**/css/*.css'
],
js: [
    'public/config.js',
    'public/application.js',
    'public/modules/*/*.js',
    'public/modules/*/*[!tests]*/*.js'
]

but how about also minifies the third-party libraries, which is installed with bower and located in public/lib/...? All the needed js and css file paths are already inside the MEAN.JS environment config file.

Meanwhile, the minified js file application.min.js is really just "minified", not "uglified", the variables' names are still the same as the original and very long.

In short, has MEAN.JS already provided any ways or functions that can "uglified" all the js and css files including third-party libraries?


Solution

  • EDIT:

    To avoid errors when uglifying 3rd party files, only include non-minified 3rd party .js files in your config/env/all.js file.


    Currently, your grunt build task uglifies your application javascript files but not your 3rd party javascript files. It does this via the uglify task in your grunt.js file.

    uglify: {
     production: {
      options: {
        mangle: false
      },
      files: {
        'public/dist/application.min.js': 'public/dist/application.js'
      }
     }
    },
    

    If you want to uglify your 3rd party files I suggest taking the following steps:

    Add your vendor files to your grunt.js file and the uglify task:

    Change the configuration object (around line 170) to include your vendor files:

    // A Task for loading the configuration object
    grunt.task.registerTask('loadConfig', 'Task that loads the config into a grunt option.', function() {
        var init = require('./config/init')();
        var config = require('./config/config');
    
        // insert vendor files
        grunt.config.set("vendorJavaScriptFiles", config.assets.lib.js);
        // note: you can do the same for your css files
        grunt.config.set("vendorCSSFiles", config.assets.lib.css);
    
        grunt.config.set('applicationJavaScriptFiles', config.assets.js);
        grunt.config.set('applicationCSSFiles', config.assets.css);
    });
    

    Add your vendorJavaScriptFiles to your uglify task:

    uglify: {
        production: {
            options: {
                mangle: false
            },
            files: {
                'public/dist/application.min.js': 'public/dist/application.js',
                'public/dist/vendor.min.js': '<%= vendorJavaScriptFiles %>'
            }
        }
    }
    

    Change your config/env/production.js file to reflect your new vendor.min file:

    assets: {
        lib: {
            css: [
                'public/lib/bootstrap/dist/css/bootstrap.min.css',
                'public/lib/bootstrap/dist/css/bootstrap-theme.min.css',
                // note you can follow a similar process for your css files
            ],
            js: 'public/dist/vendor.min.js'
        },
        css: 'public/dist/application.min.css',
        js: 'public/dist/application.min.js'
    }
    

    Now, when you run grunt build you should get both an applicaiton.min.js file and a vendor.min.js file in your public/dist/ folder.

    I separated them out for clarity, but you could combine them into one application.min.js file if you prefer.

    Here is a much more detailed description of the process: https://blog.dylants.com/2014/11/19/bundling-production-assets-for-mean-js/

    Hope this helps.