Add grunt to an existing App built on AngularJS

774 views Asked by At

I have an AngularJS application that was built without yeo, grunt, bower etc.. This is currently done via Rails. But due to certain issues, we are in the process of separating AngularJS app separate from Rails and to use Rails purely as API.

  • How do i integrate grunt to the existing app? Whether this is even possible.?
  • Pit-falls?

As per current architecture of the app, controllers, services, templates, filters, directives are all in separate folders.

  • Is there any particular folder structure needed to implement grunt?

Basic things that need to be done:

  • Compress source files into one(controllers into 1 controller, etc)
  • Minify

Current gruntFile

module.exports = function(grunt) {
    require('load-grunt-tasks')(grunt);

    grunt.initConfig({
        pkg: grunt.file.readJSON("package.json"),


        clean: ['js/dist/**/*.js'], 
        concat: {
            controllers: {
                src: ['js/controllers/*.js'],
                dest: 'js/dist/controller.js'
            },
            models: {
                src: ['js/services/*.js'],
                dest: 'js/dist/service.js'
            }
        },
        uglify: {
            options: {
              mangle: false
            },
            my_target: {
                files: {
                    'js/dist/controller.min.js': ['js/dist/controller.js'],
                    'js/dist/service.min.js': ['js/dist/service.js'],
                    'js/dist/filters.min.js': ['js/filters/filters.js'],
                    'js/dist/directives.min.js': ['js/directives/custom.js'],
                    'js/dist/app.min.js': ['js/app.js']
                }
            }
        },
        imagemin: {
            dynamic: {
                files: [{
                    expand: true,
                    cwd: 'assets/images/',
                    src: ['**/*.{png,jpg,gif}'],
                    dest: 'assets/images/'
                }]
            }
        }
    });

    grunt.registerTask('default', ['clean','concat','uglify']);
};

How do i start? Sorry if this seems obvious, but this would be the first time with grunt and hence would like to get proper advice.

1

There are 1 answers

0
Billy On

It doesn't really matter how far into your project you are. You can still use grunt to build your application.

What I usually do is clean and copy everything first to a build/dist folder like so:

clean: {
    all: {
        src: ['build']
    },
    old: {
        src: ['build/public/app.js']
    }
},

copy: {
    client: {
        files: [
            {
                expand: true,
                cwd: 'public/',
                src: ['**', '!**javascripts/**', '!**stylesheets/**', '!**views/**'],
                dest: 'build/public',
                filter: 'isFile',
                flatten: false
            }
        ]
    },
    vendor: {
        files: [
            {
                expand: true,
                src: ['public/javascripts/vendor/*'],
                dest: 'build/public/javascripts/vendor/',
                filter: 'isFile',
                flatten: true
            }
        ]
    },
    server: {
        files: [
            {
                expand: true,
                src: ['**', '!public/**', '!Gruntfile.js', '!**nbproject/**', '!access.log', '!files/**/*'], 
                dest: 'build/',
                filter: 'isFile'
            }
        ]
    }
},

Note the !**nbproject/** if you are using Netbeans as IDE to exclude that folder. I have a lot of files(attachments) in this specific project, so I also exclude the files folder. You probably neither want to include your log files.

Then I concatenate the desired files and uglify the output:

concat: {
    options: {
        separator: ';'
    },
    dist: {
        src: ['public/javascripts/app.js', 'public/javascripts/controllers/*', 'public/javascripts/directives/*', 'public/javascripts/services/*'],
        dest: 'build/public/app.js'
    }
},
uglify: {
    options: {
        banner: '/*! <%= pkg.name %> Version : <%= pkg.version %> \n * Build date: <%= grunt.template.today("dd-mm-yyyy") %>\n */\n',
    },
    dist: {
        files: [
            {
                'build/public/app.min.js': ['build/public/app.js']
            }
        ]
    }
},

I like to add a banner to the file, including version, date etc. Of course, if you want to, you can also minify you HTML and CSS.

Don't forget to load your tasks, e.g. grunt.loadNpmTasks('grunt-contrib-clean');.

You can integrate this in any app, new or far into development.