Ronnie
Ronnie

Reputation: 11198

Angular minification with grunt results in 'Failed to instantiate module' error

I am aware of setting up a controller, service, model etc for prepping for minification. I have about 20 controllers, models and services as individual files and I want to minify and concat them all into one JS file for production.

To get an idea of how I have these files setup, here is an example:

VforumJS.controller('MainController', ['$scope', '$location', '$sce', 'MainModel', 'LogModel', 'MainDebug', 'timecode', 'Idle', function($scope, $location, $sce, MainModel, LogModel, MainDebug, timecode, Idle)
{
  ...
}]);

After minification, I get the error

Failed to instantiate module VforumJS due to:
  Error: [$injector:unpr] http://errors.angularjs.org/1.4.1/$injector/unpr?p0=a

If I click the error link, it says Unknown provider: a

Here is where my module gets created

var VforumJsConfig = function($routeProvider, $locationProvider, localStorageServiceProvider)
{
  localStorageServiceProvider.setPrefix('vforumdesktop');
  $locationProvider.html5Mode(true);

  $routeProvider
  .when('/', {
    ...
  })
  .otherwise({
    ...
  });
};

var VforumJS = angular.module('VforumJS', ['ngRoute','LocalStorageModule', 'ngTouch', 'ui-rangeSlider','base64','ngIdle'])
.config(['$routeProvider', '$locationProvider', 'localStorageServiceProvider', VforumJsConfig])
.constant('LogTypes', {
  LOGIN:          1,
  IDLE_LOGOUT:    2,
  MANUAL_LOGOUT:  3,
  VFORUM_OPEN:    4,
  VFORUM_CLOSE:   5
})
.constant('SendLogs', false)
.constant('MainDebug', true);

Am I maybe not doing the proper minification prep in the above code where the module is created?

Here is my Gruntfile.js

'use strict';

module.exports = function(grunt)
{
  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    uglify: {
      all_src: {
        options: {
          sourceMap: true,
          sourceMapName: 'source.map'
        },
        src: 'resources/js/**/*.js',
        dest: 'composite.all.min.js'
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.registerTask('default', ['uglify']);
};

Upvotes: 6

Views: 1461

Answers (3)

Phil
Phil

Reputation: 1069

Use the array syntax for VforumJsConfig so that the dependencies are defined explicitly rather than implied by the parameter names which will be minified. Instead of:

var VforumJsConfig = function($routeProvider, $locationProvider, 

localStorageServiceProvider)
{
  localStorageServiceProvider.setPrefix('vforumdesktop');
  $locationProvider.html5Mode(true);

  $routeProvider
  .when('/', {
    ...
  })
  .otherwise({
    ...
  });
};

Try:

var VforumJsConfig = ['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider, localStorageServiceProvider)
{
  localStorageServiceProvider.setPrefix('vforumdesktop');
  $locationProvider.html5Mode(true);

  $routeProvider
  .when('/', {
    ...
  })
  .otherwise({
    ...
  });
}];

Upvotes: 0

shieldstroy
shieldstroy

Reputation: 1327

Your .config is definitely one of the issues. Double check and make sure that everywhere in your code that you are injecting a service/provider that you are using the in-line minification.

This is what a config injecting one provider (just $logProvider for this example) will look like after minification:

.config(function(a){
  console.log("Never gets here, but a is", a);
})

When really it should look like this:

.config(['$logProvider', function(a){
  console.log("a is", a);
}])

Here is a codepen: http://codepen.io/troylelandshields/pen/xGjKGV

Upvotes: 2

chrisvans
chrisvans

Reputation: 248

Your VforumJsConfig line is the issue

var VforumJsConfig = function($routeProvider, $locationProvider, localStorageServiceProvider)

The function parameters get minified, and angular doesn't know where to inject them from. You need to supply them as strings ( just like your other functions ), as strings won't be altered during minification.

From the docs: https://docs.angularjs.org/tutorial/step_05#a-note-on-minification

So you will need to add after the definition of VforumJsConfig:

VforumJsConfig.$inject = ['$routeProvider', '$locationProvider', 'localStorageServiceProvider']

Upvotes: 0

Related Questions