Modules

Boo follows a strict mapping of one module per file, in other words, each source file is a module. From its .Net roots however there is also the concept of namespaces, which allow to expose multiple modules under a single export point.

In BooJs that mechanism is respected and mapped to what is known as the AMD pattern in the Javascript world. The reason why this pattern was chosen instead of something like Node.js require is that BooJs code can be targeted to run on a browser too, where synchronous loading of code is not widely supported.

Here is an example Boo module and the generated Javascript code with annotations:

namespace example

import myapp

def foo(s):
    notify(s)

foo("Hello")
// Namespace serves as ID and is mapped to exports so we can augment it
// Boo runtime is always passed as a dependency
// Imports are passed as additional dependencies
Boo.define('example', ['exports', 'Boo', 'myapp'], function (exports, Boo, myapp) {
    // Type definitions of the module
    function foo(s) {
        myapp.notify(s);
    }
    // Public types are exported
    exports.foo = foo;
});

// Namespace is mapped to exports
// Boo runtime is again always passed as a dependency
// Imports are passed as additional dependencies
Boo.require(['example', 'Boo', 'myapp'], function (exports, Boo, myapp) {
    // Executable portion of the module
    exports.foo("Hello");
});

One difference with the AMD spec is that define and require are not global symbols but instead are referenced from the Boo runtime (eg. Boo.define). This is done to avoid a dependency or conflict with an AMD loader in the environment, BooJs includes all the needed functionality to manage AMD style dependencies. If you wish to use a more powerful loader you can just point Boo.define and Boo.require to require.js for example.

BooJs default AMD loader does not automatically fetch dependencies from disk or a web server, it expects all the dependencies to be loaded up front, its job is only to resolve them in the correct order. Since in BooJs the deployable unit is an assembly and not a module this works quite well, you just need to remember to load all the generated assemblies in your environment. For automatic loading of dependencies you can easily integrate with require.js or any other module loader that conforms to the AMD pattern.

Note

For Node.js environments a custom wrapper for the loader is in the roadmap, it will take care of automatically importing referenced dependencies.

To call BooJs modules from your Javascript code you can use Boo.require to obtain the desired module.

var example = Boo.require('example');
example.foo("Hello");
// ... or ...
var foo = Boo.require('example').foo;
foo("Hello");