Goal: to organize our code base in a way that make it easy (for everyone on the development team) to navigate through the code and quickly locate the pieces that are relevant to a specific feature or section of the application.
`Care Bear Stare` the Directory Structure
Best Practice Principles are explained in great detail in the Angular Style Guide
Instead we should put each feature/entity in its own file. Each stand-alone controller will be defined in its own file, each component will be defined in each own file, etc.
Group Files into directories by feature
Let's say for example,have a section in our application that lists features, we will put all related files into a feature-list/ directory under app/
If a feature is used across an application put it inside app/core.
Other typical names for our core directory are shared, common and components. The last one is kind of misleading though, as it will contain other things than components as well.
(This is mostly a relic of the past, when "components" just meant the generic building blocks of an application.)
app/
feature-list/
feature-list.component.js
feature-list.component.spec.js
app.jsExample of featureList feature directory/file layout
Using Modules
A benefit of having a modular architecture is code reuse - not only inside the same application, but across applications.
To make code reuse frictionless:
How you used to register a module with an app
angular.
module('featureApp').
component('featureList', ...);
How it should be done:
app/
feature-list/
feature-list.module.js
feature-list.component.js
feature-list.component.spec.js
app.module.jsapp/feature-list/feature-list.module.js
// Define the `featureList` module
angular.module('featureList', []);
app/feature-list/app.module.js
// Define the `featureApp` module
angular.module('featureApp', [
// ...which depends on the `featureList` module
'featureList'
]);
(since app/app.js now only contains the main module declaration, we gave it a .module suffix)
By passing featureList inside the dependencies array when defining the featureApp module, Angular will make all entities registered on featureList available on featureApp as well.
app/feature-list/feature-list.component.js
// Register the `featureList` component on the `featureList` module,
angular.
module('featureList').
component('featureList', {...});Update the index.html adding a <script> tag for each JavaScript file created.
In a production-ready application, you would concatenate and minify all your JavaScript files anyway (for performance reasons), so this won't be an issue any more.
Files defining a module (i.e. .module.js) need to be included before other files that add features (e.g. components, controllers, services, filters) to that module.
Unit Test Writing Best Practice
app/feature-list/feature-list.component.spec.js:
describe('featureList', function() {
// Load the module that contains the `featureList` component before each test
beforeEach(module('featureList'));
...
});