Gerard Sans
Dec 22, 2014 · 3 min read

Ok, You know you want it. Now I will show you how to do it.

Cinemagraph — The Neverending commute

Follow me on Twitter for latest updates @gerardsans.

I am not going to tell you why but how. If you are still curious or feeling insecure, head to the links at the bottom. Now that we have cleared the air, let’s see how to do it.

I find useful to see RequireJs as taking care of file dependencies and Angular module system as taking care of instances with its DI engine. RequireJs makes sure a file is loaded before giving you the control.

Changes to index.html

There are few things to take into account.

Add RequireJs script

First we need to include a reference to RequireJs using the script tag as follows. Pick your preferred setup below.

We are telling RequireJS where to find its configuration with the data-main attribute of the script element.

Note how we omitted the .js extension. This is how RequireJs identifies files by default.

Angular changes

We need to do some changes, to delay Angular bootstrap, until RequireJs finishes loading all file dependencies.

  • Remove ng-app directive. We will bootstrap Angular to the page manually.
  • Add ng-cloak class to the body element and define ng-cloak in your site css file. This will avoid any double curly brackets from showing briefly on slow devices.

RequireJs configuration file — main.js

In main.js we set the configuration options and bootstrap Angular using a init function within the standard Angular app.js file.

In this setup we used services.js and controllers.js files to hold our list of services. You may want to use individual files for extra granularity.

We use require() to load dependencies before running our code.

Changes to app.js

We have wrapped our app module with define having only a dependency from angular. Besides, we have created a init function to manually bootstrap angular to our page.

Returning our app instance will allow us to re-use it on any of our Angular Modules

We use define() to define our modules. This can load dependencies and return an instance for our module.

Changes to Angular Modules

Up to this moment we have only covered our Angular application but left outside other Angular modules (directives, filters, services, controllers). In order to create our modules we will wrap them using define.

MainController

On our setup we don’t need to add a timeService.js dependency as services.js already includes it so it will be loaded before bootstrap and ng-controller instantiation.

Loading Sequence

This is a review of all that’s happening

  • index.html file loads.
  • All script and link tags src/href files are loaded.
  • Once require.js is loaded follows main.js.
  • RequireJs configuration is set. Initial require loads all dependencies and sub-dependencies asynchronously: app.js, services.js, controllers.js.
  • app.js file loads and define loads angular.js and creates our Angular app instance.
  • services.js file and controllers.js load with all sub-dependencies.
  • app.init gets called and angular bootstrap kicks in.
  • The page is scanned for directives, ng-controller is found and instantiated via DI. Any referenced modules are instantiated.

Asynchronous vs Synchronous

Sometimes you may need to ensure synchronous loading. Let’s write two examples using the code seen before to show how you can do that.

Our previous code to initialise Angular is asynchronous as it loads all files at the same time following the dependencies tree.

require(['app', 'services', 'controllers'], function (app) {
// initialisation code defined within app.js
app.init();
});

In order to load app first and then the rest we would do something like this.

require(['app'], function (app) {
require(['services', 'controllers'], function () {
// initialisation code defined within app.js
app.init();
});
});

app is loaded first and only after we receive the instance into app then require proceeds with loading services and controllers.

Only mention that in our proposed solution makes no sense as both services and controllers already depend on app so loading all at the same time works just fine. RequireJS walks the dependencies tree and loads each dependency respecting the precedence order.

Thanks for reading! Have any questions? Ping me on Twitter @gerardsans.

Resources

Why use RequireJs?RequireJs define APIRequireJs websiteUsing RequireJs with AngularJs, Thomas Burleson

Demo code: link

AngularZone Community

Get in touch to submit new articles or ideas

Gerard Sans

Written by

Developer Advocate @AWSCloud | Just be AWSome | MC Speaker Trainer Community Leader | Views are my own | @fullstackcon @ReactiveConf @ngcruise @UphillConf UK ☂

AngularZone Community

Get in touch to submit new articles or ideas

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade