| // Generated on 2014-08-15 using generator-webapp 0.4.9 |
| 'use strict'; |
| |
| // # Globbing |
| // for performance reasons we're only matching one level down: |
| // 'test/spec/{,*/}*.js' |
| // use this if you want to recursively match all subfolders: |
| // 'test/spec/**/*.js' |
| |
| module.exports = function (grunt) { |
| |
| // Load grunt tasks automatically |
| require('load-grunt-tasks')(grunt); |
| |
| // Time how long tasks take. Can help when optimizing build times |
| require('time-grunt')(grunt); |
| |
| // Configurable paths |
| var config = { |
| app: 'app', |
| dist: 'dist' |
| }; |
| |
| // Define the configuration for all the tasks |
| grunt.initConfig({ |
| |
| // Project settings |
| config: config, |
| |
| // Watches files for changes and runs tasks based on the changed files |
| watch: { |
| bower: { |
| files: ['bower.json'], |
| tasks: ['bowerInstall'] |
| }, |
| js: { |
| files: ['<%= config.app %>/scripts/{,*/}*.js'], |
| tasks: ['jshint'], |
| options: { |
| livereload: true |
| } |
| }, |
| jstest: { |
| files: ['test/spec/{,*/}*.js'], |
| tasks: ['test:watch'] |
| }, |
| gruntfile: { |
| files: ['Gruntfile.js'] |
| }, |
| styles: { |
| files: ['<%= config.app %>/styles/{,*/}*.css'], |
| tasks: ['newer:copy:styles', 'autoprefixer'] |
| }, |
| livereload: { |
| options: { |
| livereload: '<%= connect.options.livereload %>' |
| }, |
| files: [ |
| '<%= config.app %>/{,*/}*.html', |
| '.tmp/styles/{,*/}*.css', |
| '<%= config.app %>/images/{,*/}*' |
| ] |
| } |
| }, |
| |
| // The actual grunt server settings |
| connect: { |
| options: { |
| port: 9000, |
| open: true, |
| livereload: 35729, |
| // Change this to '0.0.0.0' to access the server from outside |
| hostname: 'localhost' |
| }, |
| livereload: { |
| options: { |
| middleware: function(connect) { |
| return [ |
| connect.static('.tmp'), |
| connect().use('/bower_components', connect.static('./bower_components')), |
| connect.static(config.app) |
| ]; |
| } |
| } |
| }, |
| test: { |
| options: { |
| open: false, |
| port: 9001, |
| middleware: function(connect) { |
| return [ |
| connect.static('.tmp'), |
| connect.static('test'), |
| connect().use('/bower_components', connect.static('./bower_components')), |
| connect.static(config.app) |
| ]; |
| } |
| } |
| }, |
| dist: { |
| options: { |
| base: '<%= config.dist %>', |
| livereload: false |
| } |
| } |
| }, |
| |
| // Empties folders to start fresh |
| clean: { |
| dist: { |
| files: [{ |
| dot: true, |
| src: [ |
| '.tmp', |
| '<%= config.dist %>/*', |
| '!<%= config.dist %>/.git*' |
| ] |
| }] |
| }, |
| server: '.tmp' |
| }, |
| |
| // Make sure code styles are up to par and there are no obvious mistakes |
| jshint: { |
| options: { |
| jshintrc: '.jshintrc', |
| reporter: require('jshint-stylish') |
| }, |
| all: [ |
| 'Gruntfile.js', |
| '<%= config.app %>/scripts/{,*/}*.js', |
| '!<%= config.app %>/scripts/vendor/*', |
| 'test/spec/{,*/}*.js' |
| ] |
| }, |
| |
| // Mocha testing framework configuration options |
| mocha: { |
| all: { |
| options: { |
| run: true, |
| urls: ['http://<%= connect.test.options.hostname %>:<%= connect.test.options.port %>/index.html'] |
| } |
| } |
| }, |
| |
| // Add vendor prefixed styles |
| autoprefixer: { |
| options: { |
| browsers: ['last 1 version'] |
| }, |
| dist: { |
| files: [{ |
| expand: true, |
| cwd: '.tmp/styles/', |
| src: '{,*/}*.css', |
| dest: '.tmp/styles/' |
| }] |
| } |
| }, |
| |
| // Automatically inject Bower components into the HTML file |
| bowerInstall: { |
| app: { |
| src: ['<%= config.app %>/index.html'], |
| exclude: ['bower_components/bootstrap/dist/js/bootstrap.js'] |
| } |
| }, |
| |
| // Renames files for browser caching purposes |
| rev: { |
| dist: { |
| files: { |
| src: [ |
| '<%= config.dist %>/scripts/{,*/}*.js', |
| '<%= config.dist %>/styles/{,*/}*.css', |
| '<%= config.dist %>/images/{,*/}*.*', |
| '<%= config.dist %>/styles/fonts/{,*/}*.*', |
| '<%= config.dist %>/*.{ico,png}' |
| ] |
| } |
| } |
| }, |
| |
| // Reads HTML for usemin blocks to enable smart builds that automatically |
| // concat, minify and revision files. Creates configurations in memory so |
| // additional tasks can operate on them |
| useminPrepare: { |
| options: { |
| dest: '<%= config.dist %>' |
| }, |
| html: '<%= config.app %>/index.html' |
| }, |
| |
| // Performs rewrites based on rev and the useminPrepare configuration |
| usemin: { |
| options: { |
| assetsDirs: ['<%= config.dist %>', '<%= config.dist %>/images'] |
| }, |
| html: ['<%= config.dist %>/{,*/}*.html'], |
| css: ['<%= config.dist %>/styles/{,*/}*.css'] |
| }, |
| |
| // The following *-min tasks produce minified files in the dist folder |
| imagemin: { |
| dist: { |
| files: [{ |
| expand: true, |
| cwd: '<%= config.app %>/images', |
| src: '{,*/}*.{gif,jpeg,jpg,png}', |
| dest: '<%= config.dist %>/images' |
| }] |
| } |
| }, |
| |
| svgmin: { |
| dist: { |
| files: [{ |
| expand: true, |
| cwd: '<%= config.app %>/images', |
| src: '{,*/}*.svg', |
| dest: '<%= config.dist %>/images' |
| }] |
| } |
| }, |
| |
| htmlmin: { |
| dist: { |
| options: { |
| collapseBooleanAttributes: true, |
| collapseWhitespace: true, |
| removeAttributeQuotes: true, |
| removeCommentsFromCDATA: true, |
| removeEmptyAttributes: true, |
| removeOptionalTags: true, |
| removeRedundantAttributes: true, |
| useShortDoctype: true |
| }, |
| files: [{ |
| expand: true, |
| cwd: '<%= config.dist %>', |
| src: '{,*/}*.html', |
| dest: '<%= config.dist %>' |
| }] |
| } |
| }, |
| |
| // By default, your `index.html`'s <!-- Usemin block --> will take care of |
| // minification. These next options are pre-configured if you do not wish |
| // to use the Usemin blocks. |
| // cssmin: { |
| // dist: { |
| // files: { |
| // '<%= config.dist %>/styles/main.css': [ |
| // '.tmp/styles/{,*/}*.css', |
| // '<%= config.app %>/styles/{,*/}*.css' |
| // ] |
| // } |
| // } |
| // }, |
| // uglify: { |
| // dist: { |
| // files: { |
| // '<%= config.dist %>/scripts/scripts.js': [ |
| // '<%= config.dist %>/scripts/scripts.js' |
| // ] |
| // } |
| // } |
| // }, |
| // concat: { |
| // dist: {} |
| // }, |
| |
| // Copies remaining files to places other tasks can use |
| copy: { |
| dist: { |
| files: [{ |
| expand: true, |
| dot: true, |
| cwd: '<%= config.app %>', |
| dest: '<%= config.dist %>', |
| src: [ |
| '*.{ico,png,txt}', |
| '.htaccess', |
| 'images/{,*/}*.webp', |
| '{,*/}*.html', |
| 'styles/fonts/{,*/}*.*' |
| ] |
| }, { |
| expand: true, |
| dot: true, |
| cwd: 'bower_components/bootstrap/dist', |
| src: ['fonts/*.*'], |
| dest: '<%= config.dist %>' |
| }] |
| }, |
| styles: { |
| expand: true, |
| dot: true, |
| cwd: '<%= config.app %>/styles', |
| dest: '.tmp/styles/', |
| src: '{,*/}*.css' |
| } |
| }, |
| |
| // Run some tasks in parallel to speed up build process |
| concurrent: { |
| server: [ |
| 'copy:styles' |
| ], |
| test: [ |
| 'copy:styles' |
| ], |
| dist: [ |
| 'copy:styles', |
| 'imagemin', |
| 'svgmin' |
| ] |
| } |
| }); |
| |
| |
| grunt.registerTask('serve', function (target) { |
| if (target === 'dist') { |
| return grunt.task.run(['build', 'connect:dist:keepalive']); |
| } |
| |
| grunt.task.run([ |
| 'clean:server', |
| 'concurrent:server', |
| 'autoprefixer', |
| 'connect:livereload', |
| 'watch' |
| ]); |
| }); |
| |
| grunt.registerTask('server', function (target) { |
| grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.'); |
| grunt.task.run([target ? ('serve:' + target) : 'serve']); |
| }); |
| |
| grunt.registerTask('test', function (target) { |
| if (target !== 'watch') { |
| grunt.task.run([ |
| 'clean:server', |
| 'concurrent:test', |
| 'autoprefixer' |
| ]); |
| } |
| |
| grunt.task.run([ |
| 'connect:test', |
| 'mocha' |
| ]); |
| }); |
| |
| grunt.registerTask('build', [ |
| 'clean:dist', |
| 'useminPrepare:html', |
| 'concurrent:dist', |
| 'autoprefixer', |
| 'concat', |
| 'cssmin', |
| 'uglify', |
| 'imagemin', |
| 'copy:dist', |
| 'rev', |
| 'usemin', |
| 'htmlmin' |
| ]); |
| |
| grunt.registerTask('default', [ |
| 'newer:jshint', |
| //'test', |
| 'build' |
| ]); |
| }; |