Skip to content

Instantly share code, notes, and snippets.

@shabin-slr
Forked from ajcrites/README.md
Created August 17, 2016 15:28
Show Gist options
  • Save shabin-slr/d9c22c8245088f5579e43c71bbc44b02 to your computer and use it in GitHub Desktop.
Save shabin-slr/d9c22c8245088f5579e43c71bbc44b02 to your computer and use it in GitHub Desktop.
Minimal AngularJS + AMD (require.js) loading plus `r.js` optimization.

Simple AngularJS + require.js "optimizable" project

NOTE: gists do not allow directories, so / cannot be included in filenames. Instead, - is used in this project. That is to say public-index.html should actually be read as public/index.html relative to the root of the project.

This is a very stripped down seed project for AngularJS-based code that is loaded via the require.js AMD and optimized via r.js

Inspired by:

Note that the public/js/MainCtrl.js file is not necessary for loading angular, but it is helpful to see that a controller can be loaded.

Purpose

This project is designed to show the basic requirements for require.config and build.js (standard name for r.js build file) in order to get an AngularJS-based project to work during development and after optimization.

Key Points

  • build.js reference to mainConfigFile is important. Otherwise the shims for angular will not exist
  • Using ng-app in HTML does not work. Instead, you have to load the Angular module yourself via angular.bootstrap

Deployment

The use of public as the application directory is simply a standard. This could be anything, and in fact another directory is not necessary. The root of the project could contain the entire project directory. It is nice for a project to expose a document root rather than the entire project, though.

dist is also a standard, but this can be renamed.

In order to run the project, you can use any server you like.

cd public
python -m SimpleHTTPServer

will work, but as long as public is the document root of the current server, the project will work.

Optimization

r.js must be installed. You can install this globally or as a node_modules module of the actual project. Whatever it takes, you will run

/path/to/r.js -o build.js

This will create the dist folder that has the same scheme as public except main.js is optimized (i.e. has all of the JavaScript code as it is needed). CSS will also be optimized -- blah blah.

At this point, you can run SimpleHTTPServer or whatever you want while under the dist directory and it should work identically to public. It's just a little harder to debug.

bower, node

Additional components for loading/running the app were omitted for simplicity. You can use whatever you like as long as the end result after r.js is run is the same.

({
// rename this to whatever the front-end files directory is
appDir: "public",
// rename this to the front end files JavaScript directory
baseUrl: "js",
// rename this to whatever the distribution directory you want is
dir: "dist",
/**
* `r.js` needs to know where `require.config` is called ahead of time
* rather than just having it be included automatically by data-main
*
* This is done so that shim definitions can be ready and `angular` will
* be properly defined as a module
*/
mainConfigFile: "public/js/main.js",
})
<!DOCTYPE html>
<!-- note that ng-app is omitted! -->
<html>
<!-- Loading require.js locally will work just fine too -->
<script data-main=js/main src=//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.9/require.min.js></script>
</html>
/**
* This file is not necessary. It's just here to prove
* that you can load a controller via require.js
*/
define(function () {
/**
* This is using an array for angular dependency injection
* syntax. You could use for example:
* `["$scope", function ($scope)` to include the scope
* Any service can be included in this way. The array syntax
* is preferred for minifcation
*/
return [function () {}];
});
/**
* Require configuration. Load angular from shim and export the
* `angular` value. This uses a CDN to load angular, but that
* is not necessary. A local file will work just fine.
*/
require.config({
shim: {
angular: {
exports: "angular",
},
},
paths: {
angular: "//code.angularjs.org/1.2.0-rc.2/angular.min",
},
});
require(["angular", "controller/MainCtrl"], function (ng, MainCtrl) {
var app = ng.module("nameOfTheAppGoesHere", []);
// this can be omitted
app.controller("MainCtrl", MainCtrl);
/**
* require.js / r.js do not play nice with Angular loading in some cases
*
* Rather than create an app via `ng-app`, you can do the bootstrapping
* here using `angular.bootstrap`
*
* Of course, you can use any element. Doesn't have to be `<html>`
*
* Note that https://github.com/tnajdek/angular-requirejs-seed
* uses `window.name = "NG_DEFER_BOOTSTRAP!";` I don't know why, but it
* doesn't actually seem to be necessary. If it is and you know why,
* let me know!
*/
// App name needs to be the same. Will make a lot of sense to parameterize it
ng.bootstrap(document.querySelector("html"), ["nameOfTheAppGoesHere"]);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment