javascript - lazy loading of components in angular with browserify -
i in process of outlining architecture of complex application based on angular. started angular-seed project , seems starting point. bothers me angular apps nature involves loading upfront. script loaders, there doesn't seems clean way around.
i came backbone.js background , there quiet straight use require.js lazy loading based on router callbacks. in angular routes defined below:
// declare app level module depends on views, , components angular.module('myapp', [ 'ngroute' ]). config(['$routeprovider', function($routeprovider) { $routeprovider.when({templateurl:'../tmpl.html',controller:'view1ctrl'}) .when({templateurl:'../tmpl.html',controller:'view1ctrl'}) .otherwise({redirectto: '/view1'}); }]);
now here, $routeprovider.when({templateurl:'../tmpl.html',controller:'view1ctrl'})
lazily load controller , template. tempted use like:
$routeprovider.when({templateurl:'../tmpl.html',controller:require('view1ctrl'})
using browserify doesn't seems clean , not require. know question has been asked several times on way or other haven't found emphatic answer this.
my preference here use browserify supports loved cjs modules in browser.
i'm not sure how browserify, i've never tried myself recommend oclazyload.
as standalone service, works wonders loading files (json, css, js, templates - name it) , injecting running angular application.
with said, works even better(imo) coupled router (the default angular one, or ui-router).
there 'seed projects' showcase how 1 oclazyload coupled systemjs.
- https://github.com/swimlane/angular-systemjs-seed
- https://github.com/lookfirst/systemjs-seed
- https://github.com/lookfirst/oclazyload-systemjs-router
- https://github.com/kasperlewau/ng-jspm-seed
but don't need that.
if go ui-router, ui-router-extras , oclazyload can put lazy load states:
main.js
/** * inject needed dependencies our main module. */ var main = angular.module('main', [ 'ui.router', 'ct.ui.router.extras.future', 'oc.lazyload' ]); /** * define lazy loaded states. */ main.constant('lazyloadedstates', [ { name: 'about', url: '/about', type: 'lazy', src: [ '/path/to/about.module.js', '/path/to/aboutcontroller.js' ] } ]); /** * setup behaviour when hit futurestate 'lazy' * type. * * 1. setup deferred object. * 2. resolve promise when every file defined in futurestate.src has been loaded. * 3. return promise. */ main.config(function ($futurestateprovider, lazyloadedstates) { $futurestateprovider.statefactory('lazy', function ($q, $oclazyload, futurestate) { var deferred = $q.defer(); $oclazyload.load(futurestate.src).then(function () { deferred.resolve(); }); return deferred.promise; }); lazyloadedstates.foreach($futurestateprovider.futurestate); });
that's 'framework' out of way - need keep adding more modules, more code, , match real state definition dummy 1 in lazyloadedstates
constant.
about.module.js
/** * setup _real_ '/about' state in lazy loaded file. */ angular.module('about', []).config(function ($stateprovider) { $stateprovider.state('about', { url: '/about', controller: 'aboutcontroller', template: 'some_template.html' }); });
aboutcontroller.js
/** * register aboutcontroller in lazy loaded file. done in about.module.js aswell, * we'll here separate stuff , showcase loading of multiple files. */ angular.module('about').controller('aboutcontroller', function ($state) { console.log('im on lazy loaded state!', $state.current); });
i hope gives rough idea of how setup lazy loaded states in angular. have yet find easier way this, i'm sure there articles out there on how couple ui-router (or default angular router) other 'lazy-loader'.
doc links: