Search code examples
javascriptangularjswebpackcommonjs

Lazy load AngularJS controllers with Webpack


I am using AngularJS 1.5.6 with Webpack.

My files architecture is:

app
|- scripts
|   |- modules
|       |- homepage
|          |- homepage.js
|          |- controller
|             |- HomepageController.js
|- app.js
|- index.html

The webpack.config (please tell me if you need to see more of this file):

module.exports = {
    context : __dirname + "/app",
    entry : {
        main: "./app.js",
        vendor: [
            'angular',
            'angular-route'
        ]
    },
[...]
};

index.html contains the import of the the js files:

<script type="text/javascript" src="vendor.js"></script>
<script type="text/javascript" src="main.js"></script>

In apps.js:

(function () {  
    'use strict';

    require('./scripts/modules/homepage/homepage');

    angular.module("NgAppProject", [
        'ngRoute',
        'ng',
        'Homepage'
    ]);
})();

In homepage.js:

(function () {
    'use strict';

    angular.module('Homepage', [
        'ngRoute',
        'ng'
    ])
    .config(['$routeProvider', '$controllerProvider', function($routeProvider, $controllerProvider) {
        $routeProvider
          .when('/home', {
            templateUrl: 'scripts/modules/homepage/views/homepage.html',
            controller: 'HomepageController',
            controllerAs: 'homepageController',
            resolve: {
                deps: function() {
                    return require.ensure([], function (require) {
                $controllerProvider.register("HomepageController", require('./controllers/HomepageController'));
                    }, '_homepage');
                }
            }
          });
    }]);
})();

The Problem:

When I start my app and go to localhost:8080/#/home, I get the error:

Error: [ng:areq] Argument 'HomepageController' is not a function, got undefined

I think it can't find my controller, but I can't figure out why.

However this works fine:

angular.module('Homepage', [
    'ngRoute',
    'ng'
])
.config(//config here)
.controller("HomepageController", require('./controllers/HomepageController'));

I would really welcome any help, thank you!


Solution

  • I think that require.ensure not return promise. So, you can try this approach:

    resolve: {
      deps: ['$q', function($q) {
        var deferred = $q.defer();
        require.ensure([], function(require) {
          $controllerProvider.register("HomepageController", require('./controllers/HomepageController'));
          deferred.resolve();
        }, '_homepage');
        return deferred.promise;
      }]
    }