A friendly integration of AngularJS into RequireJS powered applications
This project seamlessly integrates AngularJS into RequireJS based applications.
Using ngDefine you can leverage RequireJS to package AngularJS modules into reusable components.
ngDefine('my.module', [
'jquery',
'./bar',
'module:ngResource',
'module:my.other.module:my-other-module'
], function(module, $) {
// define the module
module.value("foo", "bar");
});
ngDefine allows you to declare both plain RequireJS dependencies and AngularJS modules that get resolved using RequireJS before the module definition callback is called.
It instantiates the AngularJS module with dependencies to other modules that may be declared via module:[moduleName]:[moduleLocation]
.
The library supports minification that reduces module definitions to plain AngularJS / RequireJS.
AngularJS modules are defined via the ngDefine function:
ngDefine('app', function(module) {
// module => { .., name: 'app', .. }
module.value('foo', 'bar');
});
The function accepts a module name, an optional list of module dependencies and a module definition body.
The list of dependencies may contain AngularJS module dependencies in the form
module:{angularModuleName}[:{requireJsPath}]
.
The optional requireJsPath
is used to map the AngularJS module to a RequireJS location.
If no path is given, the RequireJS path is produced by replacing all .
with /
.
ngDefine('app', [
// require normal requireJS packages
'angular',
'jquery',
// require package local files
'./foo',
// require angular modules
'module:ngResource:angular-resource',
'module:my.module.bar:my-module/bar',
'module:my.other.module:my-other-module',
// require without a require js path -> locates the module under
// foo/baz
'module:foo.baz'
],
function(module, angular, jquery) {
// callback gets passed the defined module as the first
// parameter, all other objects defined by declared
// dependencies follow at parameters 1..n
module // --> { .., name: 'app', .. }
// define module now
module.value("foo", "bar");
});
A require configuration using ngDefine / AngularJS may look as follows:
require({
paths: {
// include ngDefine script in path
'ngDefine' : 'lib/ngDefine',
'angular' : 'lib/angular/angular',
// optional dependencies
'angular-resource' : 'lib/angular/angular-resource'
'jquery' : 'lib/jquery/jquery'
},
shim: {
'angular' : { deps: [ 'jquery' ], exports: 'angular' },
'angular-resource': { deps: [ 'angular' ] }
},
packages: [
// application package
{ name: 'app', location: 'app' },
// other angular modules
{ name: 'my-module', location: 'lib/my-module' },
{ name: 'my-other-module', location: 'lib/my-other-module' }
]
});
The following piece of code may then be used to bootstrap the application:
// require ngDefine and all angular modules your app requires
require([ 'ngDefine', 'angular' ], function(ngDefine, angular) {
// require the application
require(['app'], function() {
// bootstrap the application
angular.bootstrap(document.body, ['app']);
});
});
It ensures that ngDefine is loaded before the application modules are defined. Additionally it bootstraps the AngularJS application after the application and its dependencies have been resolved.
The library provides the script ngr.js that can be used to minify modules created using ngDefine. ngr.js is a wrapper to the RequireJS and works in NodeJS and browser environments.
To expose the script as the ngr task into grunt, use the following code snippet:
// project configuration
grunt.initConfig({
// ...
ngr: {
minify: {
// supports all options r.js understands
options: {
name : 'app/main',
out: 'build/app.min.js'
// path, shim and package configurations
// ...
}
}
}
});
// sample task for ngDefine optimization
grunt.registerMultiTask('ngr', 'Minify app', function() {
var done = this.async();
var ngr = require('path/to/ngr.js');
ngr.optimize(this.data.options, function() {
done('success');
}, function(e) {
console.log('Error during minify: ', e);
done(new Error('With failures: ' + e));
});
});
AngularJS offers a dependency injection mechanism at runtime. When building applications a developer must know which script files to include into his application so that all runtime dependencies are met when the application is bootstrapped. AngularJS does not allow application developers to define these dependencies on the file level. However, that is exactly what RequireJS does.
ngDefine simply employs RequireJS and gives developers the ability to declare AngularJS modules and their dependencies in a portable way. This way the modules can be reused and external dependencies can easily be resolved.
Not quite, read again. There is no gap between RequireJS and AngularJS, as both serve different purposes during different stages of the application lifecycle. ngDefine allows you to leverage the power of both technologies.
Yes, minification can be done.
Use under terms of MIT license.