title: Angular module not available after grunt build
body: <p>I'm fairly new to angular, grunt, bower, node and all this stuff, and I am facing a problem when trying to build my project using grunt.</p>
  
  <p>I used the <strong>angular-php</strong> yeoman generator, that is based in <strong>generator-angular</strong>, and I have been developing using grunt serve without any problems.</p>
  
  <p>The problem comes when I try to build the project for production with <strong>grunt build</strong>. The process works ok, but when I try to load the application, I get this error in the console:</p>
  
  <pre><code>vendor.d4e4dfe8.js:10420 Uncaught Error: [$injector:modulerr] Failed to instantiate module lossanroquerApp due to:
  Error: [$injector:modulerr] Failed to instantiate module uiGmapgoogle-maps due to:
  Error: [$injector:nomod] Module 'uiGmapgoogle-maps' is not available! You either misspelled the module name or forgot to load it. If registering a module ensure that you specify the dependencies as the second argument.
  http://errors.angularjs.org/1.5.7/$injector/nomod?p0=uiGmapgoogle-maps
      at http://localhost:8888/scripts/vendor.d4e4dfe8.js:10420:12
      at http://localhost:8888/scripts/vendor.d4e4dfe8.js:12427:17
      at ensure (http://localhost:8888/scripts/vendor.d4e4dfe8.js:12351:38)
      at module (http://localhost:8888/scripts/vendor.d4e4dfe8.js:12425:14)
      at http://localhost:8888/scripts/vendor.d4e4dfe8.js:14960:22
      at forEach (http://localhost:8888/scripts/vendor.d4e4dfe8.js:10673:20)
      at loadModules (http://localhost:8888/scripts/vendor.d4e4dfe8.js:14944:5)
      at http://localhost:8888/scripts/vendor.d4e4dfe8.js:14961:40
      at forEach (http://localhost:8888/scripts/vendor.d4e4dfe8.js:10673:20)
      at loadModules (http://localhost:8888/scripts/vendor.d4e4dfe8.js:14944:5)
  http://errors.angularjs.org/1.5.7/$injector/modulerr?p0=uiGmapgoogle-maps&amp;p…0(http%3A%2F%2Flocalhost%3A8888%2Fscripts%2Fvendor.d4e4dfe8.js%3A14944%3A5)
      at http://localhost:8888/scripts/vendor.d4e4dfe8.js:10420:12
      at http://localhost:8888/scripts/vendor.d4e4dfe8.js:14983:15
      at forEach (http://localhost:8888/scripts/vendor.d4e4dfe8.js:10673:20)
      at loadModules (http://localhost:8888/scripts/vendor.d4e4dfe8.js:14944:5)
      at http://localhost:8888/scripts/vendor.d4e4dfe8.js:14961:40
      at forEach (http://localhost:8888/scripts/vendor.d4e4dfe8.js:10673:20)
      at loadModules (http://localhost:8888/scripts/vendor.d4e4dfe8.js:14944:5)
      at createInjector (http://localhost:8888/scripts/vendor.d4e4dfe8.js:14866:19)
      at doBootstrap (http://localhost:8888/scripts/vendor.d4e4dfe8.js:12103:20)
      at bootstrap (http://localhost:8888/scripts/vendor.d4e4dfe8.js:12124:12)
  http://errors.angularjs.org/1.5.7/$injector/modulerr?p0=lossanroquerApp&amp;p1=…(http%3A%2F%2Flocalhost%3A8888%2Fscripts%2Fvendor.d4e4dfe8.js%3A12124%3A12)
  </code></pre>
  
  <p>I made my investigation for why could this be happening, and I understand that angular is trying to load a module before it's defined/loaded. I checked the vendor.js file just in case the module were missing, but the module is in the script file. Also I have disabled the minification and uglify tasks to make sure there was nothing broken.</p>
  
  <p>This error happens in various modules, because I tried to change the order of the scripts in the index.html and when I fix one, it happens to another.</p>
  
  <p>Here is my actual index.</p>
  
  <pre><code>&lt;!doctype html&gt;
  &lt;html class="no-js"&gt;
    &lt;head&gt;
      &lt;meta charset="utf-8"&gt;
      &lt;title&gt;&lt;/title&gt;
      &lt;meta name="description" content=""&gt;
      &lt;meta name="viewport" content="width=device-width"&gt;
      &lt;!-- Place favicon.ico and apple-touch-icon.png in the root directory --&gt;
      &lt;!-- build:css(.) styles/vendor.css --&gt;
      &lt;!-- bower:css --&gt;
      &lt;link rel="stylesheet" href="bower_components/textAngular/dist/textAngular.css" /&gt;
      &lt;link rel="stylesheet" href="bower_components/angular-tooltips/dist/angular-tooltips.min.css" /&gt;
      &lt;!-- endbower --&gt;
      &lt;!-- endbuild --&gt;
      &lt;!-- build:css(.tmp) styles/main.css --&gt;
      &lt;link rel="stylesheet" href="styles/main.css"&gt;
      &lt;link rel="stylesheet" href="styles/welcome.css"&gt;
      &lt;link rel="stylesheet" href="styles/generic.css"&gt;
      &lt;link rel="stylesheet" href="styles/player.css"&gt;
      &lt;link rel="stylesheet" href="styles/news.css"&gt;
      &lt;link rel="stylesheet" href="styles/tour.css"&gt;
      &lt;link rel="stylesheet" href="styles/discography.css"&gt;
      &lt;link rel="stylesheet" href="styles/gallery.css"&gt;
      &lt;link rel="stylesheet" href="styles/video.css"&gt;
      &lt;!-- endbuild --&gt;
  
        &lt;base href="/"&gt;
    &lt;/head&gt;
    &lt;body ng-app="lossanroquerApp"&gt;
        &lt;div class="background-image" ng-class="[{true: 'bgtransition'}[welcome], {true: 'unblurred'}[fromWelcome]]"&gt;&lt;/div&gt;
      &lt;!--[if lt IE 7]&gt;
        &lt;p class="browsehappy"&gt;You are using an &lt;strong&gt;outdated&lt;/strong&gt; browser. Please &lt;a href="http://browsehappy.com/"&gt;upgrade your browser&lt;/a&gt; to improve your experience.&lt;/p&gt;
      &lt;![endif]--&gt;
  
      &lt;!-- Add your site or application content here --&gt;
      &lt;div id="mainView" class="{{pageClass}} fromWelcome-{{fromWelcome}}" transitionend="cleanFromWelcome" ui-view&gt;&lt;/div&gt;
      &lt;div class="playerMainContainer" ng-include="'views/player.html'" &gt;&lt;/div&gt;
  
  
      &lt;!-- Google Analytics: change UA-XXXXX-X to be your site's ID --&gt;
       &lt;script&gt;
         (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
         (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
         m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
         })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
  
         ga('create', 'UA-XXXXX-X');
         ga('send', 'pageview');
      &lt;/script&gt;
  
      &lt;!--[if lt IE 9]&gt;
      &lt;script src="bower_components/es5-shim/es5-shim.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/json3/lib/json3.min.js"&gt;&lt;/script&gt;
      &lt;![endif]--&gt;
  
      &lt;!-- build:js(.) scripts/vendor.js --&gt;
      &lt;!-- bower:js --&gt;
      &lt;script src="bower_components/jquery/dist/jquery.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/angular/angular.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/json3/lib/json3.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/affix.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/alert.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/button.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/carousel.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/collapse.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/dropdown.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/tab.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/transition.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/scrollspy.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/modal.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/tooltip.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/bootstrap-sass-official/vendor/assets/javascripts/bootstrap/popover.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/angular-resource/angular-resource.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/angular-cookies/angular-cookies.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/angular-sanitize/angular-sanitize.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/angular-animate/angular-animate.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/angular-touch/angular-touch.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/angular-route/angular-route.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/angular-ui-router/release/angular-ui-router.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/ngInfiniteScroll/build/ng-infinite-scroll.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/animation-frame/AnimationFrame.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/lodash/lodash.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/shifty/dist/shifty.min.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/underscore/underscore.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/rekapi/dist/rekapi.min.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/spark-scroll/src/spark-scroll.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/angular-fontawesome/dist/angular-fontawesome.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/rangy/rangy-core.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/rangy/rangy-classapplier.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/rangy/rangy-highlighter.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/rangy/rangy-selectionsaverestore.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/rangy/rangy-serializer.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/rangy/rangy-textrange.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/textAngular/dist/textAngular.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/textAngular/dist/textAngular-sanitize.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/textAngular/dist/textAngularSetup.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/amplitude/js/amplitude.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/angular-socialshare/dist/angular-socialshare.min.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/angular-tooltips/dist/angular-tooltips.min.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/angular-simple-logger/dist/angular-simple-logger.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/markerclustererplus/src/markerclusterer.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/google-maps-utility-library-v3-markerwithlabel/dist/markerwithlabel.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/google-maps-utility-library-v3-infobox/dist/infobox.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/google-maps-utility-library-v3-keydragzoom/dist/keydragzoom.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/js-rich-marker/src/richmarker.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/angular-google-maps/dist/angular-google-maps.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/angular-youtube-api-factory/dist/angular-youtube-api-factory.min.js"&gt;&lt;/script&gt;
      &lt;script src="bower_components/ng-youtube-embed/src/ng-youtube-embed.js"&gt;&lt;/script&gt;
      &lt;!-- endbower --&gt;
        &lt;script src="node_modules/angulargrid/angulargrid.min.js"&gt;&lt;/script&gt;
      &lt;!-- endbuild --&gt;
  
  
          &lt;!-- build:js({.tmp,app}) scripts/scripts.js --&gt;
          &lt;script src="scripts/app.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/controllers/main.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/controllers/about.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/controllers/welcome.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/directives/transitionend.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/controllers/home.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/controllers/player.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/services/newsservice.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/directives/mobileonly.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/controllers/news.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/services/shows.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/controllers/tour.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/controllers/discography.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/services/albums.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/directives/initamplitudeonlast.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/controllers/gallery.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/controllers/video.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/controllers/bio.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/controllers/contact.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/directives/loading.js"&gt;&lt;/script&gt;
          &lt;script src="scripts/services/gallery.js"&gt;&lt;/script&gt;
          &lt;!-- endbuild --&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>My app.js:</p>
  
  <pre><code>'use strict';
  
  angular
    .module('lossanroquerApp', [
      'ngAnimate',
      'ngCookies',
      'ngResource',
      'ngRoute',
      'ngSanitize',
      'ngTouch',
      'ui.router',
      'gilbox.sparkScroll',
      'picardy.fontawesome',
      '720kb.socialshare',
      '720kb.tooltips',
      'uiGmapgoogle-maps',
      'infinite-scroll',
      'angularGrid',
      'jtt_youtube',
      'ngYoutubeEmbed'
    ])
    .config(function ($stateProvider, $urlRouterProvider, $locationProvider
      $locationProvider.html5Mode({
          enabled: true,
          requireBase: false
      }).hashPrefix('!');
  
  
      $urlRouterProvider.otherwise('/home');
  
      $stateProvider
        .state('main', {
          templateUrl: 'views/main.html',
          controller: 'MainCtrl'
        });
    });
  
  angular.module('infinite-scroll').value('THROTTLE_MILLISECONDS', 250);
  </code></pre>
  
  <p>And my Gruntfile.js</p>
  
  <pre><code>// Generated on 2016-06-21 using generator-angular-php 0.6.3
  '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);
  
    // grunt-connect-proxy middleware to serve PHP
    var proxyMiddleware = function (connect, options) {
      var middlewares = [];
      var directory = options.directory || options.base[options.base.length - 1];
      if (!Array.isArray(options.base)) {
        options.base = [options.base];
      }
  
      // Setup the proxy
      middlewares.push(require('grunt-connect-proxy/lib/utils').proxyRequest);
  
      options.base.forEach(function(base) {
        // Serve static files.
        middlewares.push(connect.static(base));
      });
  
      // Make directory browse-able.
      middlewares.push(connect.directory(directory));
  
      return middlewares;
    };
  
    // Configurable paths for the application
    var appConfig = {
      app: require('./bower.json').appPath || 'app',
      dist: 'dist'
    };
  
    // Define the configuration for all the tasks
    grunt.initConfig({
  
      // Project settings
      yeoman: appConfig,
  
      // Watches files for changes and runs tasks based on the changed files
      watch: {
        bower: {
          files: ['bower.json'],
          tasks: ['wiredep']
        },
        js: {
          files: ['&lt;%= yeoman.app %&gt;/scripts/{,*/}*.js'],
          tasks: ['newer:jshint:all'],
          options: {
            livereload: '&lt;%= connect.options.livereload %&gt;'
          }
        },
        jsTest: {
          files: ['test/spec/{,*/}*.js'],
          tasks: ['newer:jshint:test', 'karma']
        },
        compass: {
          files: ['&lt;%= yeoman.app %&gt;/styles/{,*/}*.{scss,sass}'],
          tasks: ['compass:server', 'autoprefixer']
        },
        gruntfile: {
          files: ['Gruntfile.js']
        },
        livereload: {
          options: {
            livereload: '&lt;%= connect.options.livereload %&gt;'
          },
          files: [
            '&lt;%= yeoman.app %&gt;/api/{,{config,src,tests}/**/}/*',
            '&lt;%= yeoman.app %&gt;/{,*/}*.html',
            '.tmp/styles/{,*/}*.css',
            '&lt;%= yeoman.app %&gt;/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'
          ]
        },
        phpTest: {
          files: ['&lt;%= yeoman.app %&gt;/api/{,{config,src,tests}/**/}/*'],
          tasks: ['shell:phpTest']
        }
      },
  
      // The actual grunt server settings
      connect: {
        options: {
          port: 9024,
          // Change this to '0.0.0.0' to access the server from outside.
          hostname: 'localhost',
          livereload: 35742
        },
        proxies: [
          {
            context: '/api',
            host: 'localhost',
            port: '&lt;%= php.options.port %&gt;'
          }
        ],
        livereload: {
          options: {
            open: true,
            middleware: function (connect, options) {
                var optBase = (typeof options.base === 'string') ? [options.base] : options.base;
              return [
  //              modRewrite([
  //                '!\\.html|\\.js|\\.css|\\.png$ /index.html [L]'
  //              ]),
                  require('connect-modrewrite')([
                      '^/api/(.*) - [L]',
                      '.*/api/(.*) /api/$1',
                      '!(\\..+)$ /index.html ',
                  ]) ,
                connect.static('.tmp'),
                connect().use(
                  '/bower_components',
                  connect.static('./bower_components')
                ),
                connect.static(appConfig.app)
              ].concat(proxyMiddleware(connect, options))
              .concat(optBase.map(function(path){ return connect.static(path); }));
            }
          }
        },
        test: {
          options: {
            port: 9001,
            middleware: function (connect, options) {
              return [
                connect.static('.tmp'),
                connect.static('test'),
                connect().use(
                  '/bower_components',
                  connect.static('./bower_components')
                ),
                connect.static(appConfig.app)
              ].concat(proxyMiddleware(connect, options));
            }
          }
        },
        dist: {
          options: {
            open: true,
            base: '&lt;%= yeoman.dist %&gt;',
            middleware: proxyMiddleware
          }
        }
      },
  
      // PHP built-in server
      php: {
        options: {
          port: 8000,
          // Change this to '0.0.0.0' to access the server from outside.
          hostname: '127.0.0.1',
          router: 'api/index.php'
        },
        server: {
          options: {
            base: '&lt;%= yeoman.app %&gt;',
          }
        },
        dist: {
          options: {
            base: '&lt;%= yeoman.dist %&gt;',
          }
        }
      },
  
      // Make sure code styles are up to par and there are no obvious mistakes
      jshint: {
        options: {
          jshintrc: '.jshintrc',
          reporter: require('jshint-stylish')
        },
        all: {
          src: [
            'Gruntfile.js',
            '&lt;%= yeoman.app %&gt;/scripts/{,*/}*.js'
          ]
        },
        test: {
          options: {
            jshintrc: 'test/.jshintrc'
          },
          src: ['test/spec/{,*/}*.js']
        }
      },
  
      // Empties folders to start fresh
      clean: {
        dist: {
          files: [{
            dot: true,
            src: [
              '.tmp',
              '&lt;%= yeoman.dist %&gt;/{,*/}*',
              '!&lt;%= yeoman.dist %&gt;/.git*'
            ]
          }]
        },
        server: '.tmp'
      },
  
      // 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 app
      wiredep: {
        options: {
          cwd: ''
        },
        app: {
          src: ['&lt;%= yeoman.app %&gt;/index.html'],
          ignorePath:  /..\//
        },
        sass: {
          src: ['&lt;%= yeoman.app %&gt;/styles/{,*/}*.{scss,sass}'],
          ignorePath: /(\.\.\/){1,2}bower_components\//
        }
      },
  
      // Compiles Sass to CSS and generates necessary files if requested
      compass: {
        options: {
          sassDir: '&lt;%= yeoman.app %&gt;/styles',
          cssDir: '.tmp/styles',
          generatedImagesDir: '.tmp/images/generated',
          imagesDir: '&lt;%= yeoman.app %&gt;/images',
          javascriptsDir: '&lt;%= yeoman.app %&gt;/scripts',
          fontsDir: '&lt;%= yeoman.app %&gt;/styles/fonts',
          importPath: './bower_components',
          httpImagesPath: '/images',
          httpGeneratedImagesPath: '/images/generated',
          httpFontsPath: '/styles/fonts',
          relativeAssets: false,
          assetCacheBuster: false,
          raw: 'Sass::Script::Number.precision = 10\n'
        },
        dist: {
          options: {
            generatedImagesDir: '&lt;%= yeoman.dist %&gt;/images/generated'
          }
        },
        server: {
          options: {
            debugInfo: true
          }
        }
      },
  
      // Renames files for browser caching purposes
      filerev: {
        dist: {
          src: [
            '&lt;%= yeoman.dist %&gt;/scripts/{,*/}*.js',
            '&lt;%= yeoman.dist %&gt;/styles/{,*/}*.css',
            '&lt;%= yeoman.dist %&gt;/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}',
            '&lt;%= yeoman.dist %&gt;/styles/fonts/*'
          ]
        }
      },
  
      // 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: {
        html: '&lt;%= yeoman.app %&gt;/index.html',
        options: {
          dest: '&lt;%= yeoman.dist %&gt;',
          flow: {
            html: {
              steps: {
                js: ['concat'/*, 'uglifyjs'*/],
                css: ['cssmin']
              },
              post: {}
            }
          }
        }
      },
  
      // Performs rewrites based on filerev and the useminPrepare configuration
      usemin: {
        html: ['&lt;%= yeoman.dist %&gt;/{,*/}*.html'],
        css: ['&lt;%= yeoman.dist %&gt;/styles/{,*/}*.css'],
        options: {
          assetsDirs: ['&lt;%= yeoman.dist %&gt;','&lt;%= yeoman.dist %&gt;/images']
        }
      },
  
      // The following *-min tasks will produce minified files in the dist folder
      // By default, your `index.html`'s &lt;!-- Usemin block --&gt; will take care of
      // minification. These next options are pre-configured if you do not wish
      // to use the Usemin blocks.
      // cssmin: {
      //   dist: {
      //     files: {
      //       '&lt;%= yeoman.dist %&gt;/styles/main.css': [
      //         '.tmp/styles/{,*/}*.css'
      //       ]
      //     }
      //   }
      // },
      // uglify: {
      //   dist: {
      //     files: {
      //       '&lt;%= yeoman.dist %&gt;/scripts/scripts.js': [
      //         '&lt;%= yeoman.dist %&gt;/scripts/scripts.js'
      //       ]
      //     }
      //   }
      // },
      // concat: {
      //   dist: {}
      // },
  
      imagemin: {
        dist: {
          files: [{
            expand: true,
            cwd: '&lt;%= yeoman.app %&gt;/images',
            src: '{,*/}*.{png,jpg,jpeg,gif}',
            dest: '&lt;%= yeoman.dist %&gt;/images'
          }]
        }
      },
  
      svgmin: {
        dist: {
          files: [{
            expand: true,
            cwd: '&lt;%= yeoman.app %&gt;/images',
            src: '{,*/}*.svg',
            dest: '&lt;%= yeoman.dist %&gt;/images'
          }]
        }
      },
  
      htmlmin: {
        dist: {
          options: {
            collapseWhitespace: true,
            conservativeCollapse: true,
            collapseBooleanAttributes: true,
            removeCommentsFromCDATA: true,
            removeOptionalTags: true
          },
          files: [{
            expand: true,
            cwd: '&lt;%= yeoman.dist %&gt;',
            src: ['*.html', 'views/{,*/}*.html'],
            dest: '&lt;%= yeoman.dist %&gt;'
          }]
        }
      },
  
      // ngmin tries to make the code safe for minification automatically by
      // using the Angular long form for dependency injection. It doesn't work on
      // things like resolve or inject so those have to be done manually.
      ngmin: {
        dist: {
          files: [{
            expand: true,
            cwd: '.tmp/concat/scripts',
            src: '*.js',
            dest: '.tmp/concat/scripts'
          }]
        }
      },
  
      // Replace Google CDN references
      cdnify: {
        dist: {
          html: ['&lt;%= yeoman.dist %&gt;/*.html']
        }
      },
  
      // Copies remaining files to places other tasks can use
      copy: {
        dist: {
          files: [{
            expand: true,
            dot: true,
            cwd: '&lt;%= yeoman.app %&gt;',
            dest: '&lt;%= yeoman.dist %&gt;',
            src: [
              'api/{{config,src,vendor}/**,index.php,.htaccess}',
              '*.{ico,png,txt}',
              '.htaccess',
              '*.html',
              'views/{,*/}*.html',
              'images/{,*/}*.{webp}',
              'fonts/*'
            ]
          }, {
            expand: true,
            cwd: '.tmp/images',
            dest: '&lt;%= yeoman.dist %&gt;/images',
            src: ['generated/*']
          }, {
            expand: true,
            cwd: '.',
            src: 'bower_components/bootstrap-sass-official/vendor/assets/fonts/bootstrap/*',
            dest: '&lt;%= yeoman.dist %&gt;'
          }]
        },
        styles: {
          expand: true,
          cwd: '&lt;%= yeoman.app %&gt;/styles',
          dest: '.tmp/styles/',
          src: '{,*/}*.css'
        }
      },
  
      // Run some tasks in parallel to speed up the build process
      concurrent: {
        server: [
          'compass:server'
        ],
        test: [
          'compass'
        ],
        dist: [
          'compass:dist',
          'imagemin',
          'svgmin'
        ]
      },
  
      shell: {
        options: {
          stdout: true,
          stderr: true,
          failOnError: true
        },
        phpTest: {
          command: 'make --directory &lt;%= yeoman.app %&gt;/api test'
        },
        phpUpdate: {
          command: 'make --directory &lt;%= yeoman.app %&gt;/api update'
        }
      },
  
      // Test settings
      karma: {
        unit: {
          configFile: 'test/karma.conf.js',
          singleRun: true
        }
      }
    });
  
  
    grunt.registerTask('serve', 'Compile then start a connect web server', function (target) {
      if (target === 'dist') {
        return grunt.task.run([
          'build',
          'configureProxies',
          'php:dist',
          'connect:dist:keepalive'
        ]);
      }
  
      grunt.task.run([
        'clean:server',
        'wiredep',
        'concurrent:server',
        'autoprefixer',
        'configureProxies',
        'php:server',
        'connect:livereload',
        'watch'
      ]);
    });
  
    grunt.registerTask('server', 'DEPRECATED TASK. Use the "serve" task instead', function (target) {
      grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.');
      grunt.task.run(['serve:' + target]);
    });
  
    grunt.registerTask('test', [
      'clean:server',
      'shell:phpTest',
      'concurrent:test',
      'autoprefixer',
      'connect:test',
      'karma'
    ]);
  
    grunt.registerTask('build', [
      'clean:dist',
      'shell:phpUpdate',
      'wiredep',
      'useminPrepare',
      'concurrent:dist',
      'autoprefixer',
      'concat',
  //    'ngmin',
      'copy:dist',
  //    'cdnify',
  //    'cssmin',
  //    'uglify',
      'filerev',
      'usemin',
  //    'htmlmin'
    ]);
  
    grunt.registerTask('default', [
      'newer:jshint',
      'test',
      'build'
    ]);
  };
  </code></pre>
  
  <p>Thank you for your help</p>