When working with ES6 or TypeScript, Angular modules often follow a pattern where they use their name as the default export. Here's an example of how one of the modules in my application is set up:
const session = angular.module("smSession", [])
.service("session", SessionService)
.component("smLogin", Login)
.config(routes)
.run(loginRedirect);
export default session.name;
This approach makes declaring Angular module dependencies cleaner, as shown in this code snippet:
import angular from "angular";
import ngAnimate from "angular-animate";
import ngMaterial from "angular-material";
import uiRouter from "angular-ui-router";
let module = angular.module("myApp", [ ngAnimate, ngMaterial, uiRouter ]);
If the entire module were exported instead, you would need to access it like so:
let module = angular.module("myApp", [ ngAnimate.name, ngMaterial.name, uiRouter.name ]);
This explains why the main module declaration for angular-material
looks the way it does - it simplifies the import process by using just the module's name string. Other type definitions are considered ambient and can be used within the application without explicit imports.
EDIT: To provide further clarification, here's the source of the file imported when ngMaterial is imported:
// Required for clarity even though already required
require('angular');
// Load Angular and its dependencies
require('angular-animate');
require('angular-aria');
// Include Angular Material
require('./angular-material');
// Export the namespace
module.exports = 'ngMaterial';
It's important to note that require('./angular-material')
doesn't return anything - it simply executes the necessary setup code for the Angular module behind the scenes (similar to examples provided above). The only thing exported from the module is the name.