Components Versus Modules
A Note about Angular Modules
Avoids Global Scope
While this is similar to encapsulation, global scope collisions often occur at a higher level in an application. When libraries attempt to use the same global variables or two pieces of a large application are written to use the same global variables, this condition often causes problems. These types of collisions are becoming less frequent especially in popular third party libraries. Using module specifications further diminishes the likelihood of a global variable conflict.
Use Separate Code Files
Once your code is separated into individual components, separating that code into multiple files generally increases maintainability. Now changes to components are clearly identified in source control as changes to the associated files. The challenge is to ensure that all of the individual files are loaded into the browser correctly or combined into a single file. There are tools to help in this area including loaders and bundlers.
Once you have code separated, you need to manage which pieces of code are dependent on another. There have been several specifications developed to help manage these dependencies. While these specifications differ in their syntax, they provide two fundamental pieces: a way to define dependent modules (imports) and a way to define pieces of a module that can be used in other modules (exports). Frameworks have developed around these specifications to intelligently load the necessary modules both in the browser and in NodeJS.
The main specifications in use today are Asynchronous Module Definition (AMD), CommonJS, and the upcoming EcmaScript 2015 module specification. The AMD specification is more often used in the browser whereas CommonJS is the spec of choice in NodeJS and NPM. The EcmaScript 2015 standard seeks to eventually become the standard supported by the major browser vendors and it has some nice options for defining imports and exports.
By using a bundler, you can mitigate the performance problem by having a process run as part of a build (a Gulp task for instance) which combines all of the script files into one file. Thus, you can reference only one script in your page and the browser only has the overhead of making one HTTP request.
Furthermore, bundlers often minify your code as well making the variable names as small as possible and removing white space. Additionally, they create sourcemaps that you use to debug the code in the browser.
Finally, when you use a bundler in conjunction with a module specification, you no longer have to maintain a long list of scripts. The order of loading the scripts is inferred by the modules’ dependency tree. Browserify is a popular bundler that leverages the CommonJS module specification and JSPM works with EcmaScript 2015 modules.
The choice to dynamically load scripts or bundle them is application-specific. Oftentimes, these tools are used in conjunction with each other to minimize page load times. Popular loaders are RequireJS using the AMD specification and SystemJS using EcmaScript 2015 modules.
Angular 2 is moving towards using standards based module systems like EcmaScript 2015 making it much easier to use the latest module tooling.
This post introduces a lot of topics and future posts will look at these concepts in more detail. If there is a concept in which you are particularly interested, please leave it in the comments.