Modulus.js
Modulus provides your javascript application with a Service Locator that allows you to easily register and locate other modules.
Modulus simplifies your module definitions by autowiring module function parameters based on the paramater name. e.g. having a parameter called moduleA in your module function will result in modulus finding moduleA and passing it to your module function. By ensuring that module names are unique, we can simplify resolving modules, and eliminate the need of worrying about paths, etc.
Service Locator
Modulus is a Service Locator, in that it provides a central place to register your modules, and a means to find modules from within other modules. More specifically, Modulus is a Dynamic Service Locator, as services are registered and found at runtime.
AMD Loader
Modulus provides the ability to intelligently* load module dependencies/scripts during runtime.
You can compile your modules into one or more script files to optimize the number of http requests made at runtime.
Defining Modules
There are several options for defining modules with Modulus.
Modulus Function
Modulus provides a simplified version of the typical 'define' and 'require' functions found in other AMD libraries. To do the equivalent of define, simply pass in a named function to the 'm' or 'modulus' function. To do the equivalent of require, simply pass in a unnamed function to the 'm' or 'modulus' function. Modulus can parse the function name and parameters, thus reducing the amount of boilerplate code you need to write.
//define a module named 'moduleA' by passing in a named function. ; //require moduleA by passing in a unnamed function with a parameter named moduleA ;
Modulus Function - Explicit Define and Require
You can also opt to use a requirejs-like api, and explicitly define and require modules. Although, this api is primarily used by the modulus build when protectAgainstMinification is true (default). Since minifiers rename parameter names and remove function names, modulus provides an API which accepts a string for the module name, and an array of string names for the dependencies.
//define a module named 'moduleA' by passing in a named function. ; //require moduleA by passing in a unnamed function with a parameter named moduleA ;
Global Module Functions
In perhaps the easiest way possible, Modulus allows you to define modules with global functions. Any dependencies on other modules are simply identified via parameter names, where the parameter name matches the name of the desired module.
//defining a module is as simple as creating a function. { return prop1: 123 ; } //simply by referencing moduleA, you will get its return value passed in as the parameter value. { return prop1: moduleAprop1 %2B 1 //evaluates to 124 ; } //let modulus know to execute moduleB once init has been called. moduleBmodule = autoInit:true; //the use of global functions means that we must explicitly call init. modulus;
When using this option for defining modules, we must explicitly call 'init' so that modulus can scan the context for modules. We must also provide module metadata (via moduleB.module), and instruct Modulus to run the moduleB function once init has been called.
Context Object
You can also choose to assign modules to a namespace/context object.
var ns = {}; ns{ return prop1: 123 ; }; ns{ return prop1: moduleAprop1 %2B 1 ; }; modulus;
Runtime Configuration
Modulus offers a powerful configuration that allows you to override any function within the Modulus, allowing you to completely customize behavior. Configuration is achieved by calling the 'init' function, and passing in an object literal with the desired settings.
Shim for 3rd Party Libraries
To shim third party libraries which do not use the Modulus convention for defining modules, we can provide a shim configuration. NOTE: You do not need to specify a runtime shim config if you've specified one in your build configuration.
//shim configuration for a few common libraries. modulus; ;
AMD
The Modulus AMD API is completely customizable, allowing you to determine any convention or configuration you'd like. To get started, you'll first need to provide a 'asyncFileLoad' function.
m;
AMD Loading Behavior
Modulus attempts to load modules as quickly as possible by using this strategy: Modulus will attempt to asynchronously load any module that is not currently registered (i.e. in modulus.config._modules) when asyncFileLoad is defined. When you require a module asynchronously, the module will first be downloaded, and then it's dependencies will be downloaded simultaneously. Note: this means that the order in which the dependencies are loaded is not guaranteed. When you require a module that has already been loaded, a new asyncFileLoad request will not be made. Shim entries that are asynchronously downloaded will have dependencies loaded first. (e.g. Backbone shouldn't be loaded until underscore is) Shim entry dependencies will be downloaded simultaneously. e.g. if you require Backbone, jquery and underscore will be loaded at the same time.
Modulus offers a powerful node.js module to help you optimize your project's script files into one (or more) js files. Every aspect of the modulus build is customizable. Modulus exposes all functions through the config so you can override any behavior. The build tool's primary function is finding module dependencies and combining modules together into 1 or more js files. This helps in optimizing your web application, as it results in fewer http requests.
Install
npm install modulusjs
Build
var modulus = ; modulus;
Build Configuration
Shim
Any scripts which do not follow the modulus convention for registering modules (e.g. third party libs) can be shimmed. Shimming allows us to reference these third party libs as we would any other module in modulus. When a shim is specified for the build configuration, modulus will generate and append a call to modulus which specifies the module's name, dependencies, and a function which returns the global export of the library.
Example: Generated Modulus Function Call for jQuery
{...}; //generated modulus function call for jquery shim ;
Example Build Configuration
modulus;
Build Guidelines
Only one module per js file is allowed
The name of the file without the extension is used as the name of the module when resolving dependencies during build.
Protecting Against Minification
Minifiers will rewrite param names and in some cases remove the names of functions. To avoid issues with minification, the build process will rewrite module definitions to use strings to explicitly define a module.
Explicit Define when using the Modulus Function
//original //becomes
Explicit Define when using Global Functions
//original {...} //will get this added myModulemodule = name: 'myModule' deps:'dependency1' 'dependency2';
Explicit Define when Assigning Modules to a Context
//original var ns = {}; ns{...} //will get this added nsmyModulemodule = name: 'myModule' deps:'dependency1' 'dependency2';
Nested Requires
Modulus will also rewrite nested requires, since they can be affected by minification.
//original ; //becomes
Codio
You can play with the specs by going here and selecting Project -> Fork. View the test results here
Modulus is still in Alpha. For now, please refer to the Github page for download instructions.
Modulus is an open source project, and can be found on Github.
License
The MIT License (MIT) Copyright (c) 2013 Jason McAffee
Contribute!
Feel free to work on any open issues Setup is super simple.
Setup
git clone https://github.com/jasonmcaffee/modulus.gitcd modulusnpm installsudo npm install grunt-cli@0.1.9 -g
Build
grunt build
Release Notes
0.0.8
- Better reorder of modules. modules now ordered in dependency order (least dependend on top). A module's dependencies will always be before the module. (not always needed, but good for requires)
- Generating and appending shim functions. e.g. m('$', [], function(){ return $;} is added when jquery is shimmed.
0.0.6
- protection against minification for all modulus usage options.
0.0.1
In progress.
- Runtime configuration - basic poc of functionality working and shown on codio.
- Build configuration - basic functionality shown with grunt test-commonjs-module and src/modules.