Modules

Module Systems

The adhocracy frontend is based mainly on two technologies: TypeScript and angular.js. Both have their own module system. These two systems are very different.

TypeScript Modules

In TypeScript, each file is a module (TypeScript does in fact offer two module systems. We use external modules). A module example.ts can be imported like this:

import * as Example from "./example";

Static imports have the benefit of allowing to check for the existence of modules and for circular imports at compile time. But be aware that this is only true if you actually use the module for more than type-checking. If not, the import will be stripped after that step and no further checks will be done.

An important bit is that these imports are responsible for actually loading the required files in the browser. Without a non-stripped import, the module will just not be available.

Angular Modules

Angular modules are the place where services, directives and filters are registered. When a module depends on another one that means that it imports all of its services, directives and filters.

A module example that depends on module dependency is created like this:

var exampleModule = angular.module("example", ["dependency"]);

This mechanism happens at runtime and therefore missing dependencies and circular imports can only be detected at runtime.

How we use it

Packages

In adhocracy we create what we call a package for every reusable feature. A package may contain services, directives and filters. Each package has its own folder in Packages/.

A package may contain arbitrary TypeScript modules. These must not import any other TypeScript modules except for type-checking. There are few exceptions to that rules, e.g. Util.

In addition, there must be a TypeScript module named Module.ts that defines an angular module by exporting a variable moduleName and a function register. moduleName contains the name that should be used for this module. By convention the module name is the package name in camel case prefixed with ‘adh’. register takes angular as a first argument and registers the module with all of its services and directives.

Module.ts must also take care of importing additional code, both from other packages and from third party libraries. For other packages that can be done by importing Module.ts from that package and adding it as a angular module dependency using its moduleName. This way it is also made sure that requirejs will actually load the code.

Resources

The backend defines a set of resource and sheet types and exposes them in a meta API. Matching TypeScript classes will be generated by the mkResources.ts script that is automatically run by buildout. The resulting code can be found in a top level folder called Resources/.