Angular 2 – Simplifying Module Imports

Standard

NgModule was a late addition to Angular 2 first appearing in RC5. One of it’s main purposes is to support lazy loading but it also helps reduce the code required for exporting and importing of components, directives and pipes. This post isn’t an intro to modules, there are plenty of those out there including the great docs on the angular site linked above.

What I want to look at in this post is how we can use a small quality of life feature to simplify the importing of modules into other modules using an index.ts to export all items from a module.

Below is the typical folder structure for a simple angular 2 app with the top level app module that will serve as our entry point and a single feature module called contact. Somewhat contrived but it provides what we need.

/app
    app.component.ts
    app.component.html
    app.module.ts
    /contact
        contact.component.ts
        contact.directive.ts
        contact.pipe.ts
        contact.module.ts

ContactModule (contact.module.ts) includes our ContactComponent (contact.component.ts), ContactDirective (contact.directive.ts) and ContactPipe (contact.pipe.ts) in its exports making them available to any module that imports ContactModule.

Our AppComponent (app.component.ts) wants to use the ContactComponent and ContactDirective so we must import them into our AppModule (app.module.ts). It doesn’t need the Pipe.

Our AppModule will look something like this:

//Import the module and individually the Component and Directive
import { ContactModule }    from './contact/contact.module';
import { ContactComponent } from './contact/contact.component';
import { ContactDirective } from './contact/contact.directive';

@NgModule({
    imports: [ContactModule],
    exports: [],
    declarations: [AppComponent]
})
export class AppModule() {}

Even though we import the module ContactModule we must also include the imports for the ContactComponent and ContactDirective or neither of them will be available inside AppModule.

If the ContactModule is imported into lots of other modules this can lead to repetitive code. If we add something new to ContactModule we’d need to add the imports to each module that already imports ContactModule. Bit of a pain!

The solution to this is to create a “feature exports” file for all the exports from our contact feature. We only have to then import this file defining the items we want to use. Also, if we name this file index.ts we can also omit the filename when defining the import statement in the imorting module.

The new folder structure will now look as follows including our new index.ts file in the feature folder:

/app
    app.component.ts
    app.component.html
    app.module.ts
    /contact
        contact.component.ts
        contact.directive.ts
        contact.pipe.ts
        contact.module.ts
        index.ts

index.ts will contain the following:

export { ContactComponent } from './contact.component';
export { ContactDirective } from './contact.directive';
export { ContactPipe }      from './contact.pipe';
export { ContactModule }    from './contact.module';

Now when we want to import the contact feature module into our app module we just need to import the “feature file” for which we don’t even have to specify the filename due to convention just the feature folder name…nice!:

//Import what we need from the 'contact feature'
import { ContactComponent, ContactDirective } from './contact';

@NgModule({
    imports: [ContactModule],
    exports: [],
    declarations: []
})

Advertisements

The state of Angular 2 Tooling

Standard

The Angular 2 framework has now been released so it’s a great time to jump in and learn the ropes. However, whilst we can relax our attention on the changing API’s in the framework for a short time, we’re still faced with the endlessly changing world of front end tooling.

Webpack is currently top of the pile for all of our developer workflow needs. But what else is there and where do we start?

Angular cli

A fork of the ember cli that’s recently been updated to support webpack replacing systemjs. This is almost certainly going to be the dominant player going forward as it has some prominent angular community contributors. Remember that much of the featureset comes from webpack rather than the cli itself.

For:
  1. Your lowest friction option for getting a project up an running.
  2. The generators are really useful for creating the often repeated boilerplate in an Angular app.
  3. The generators help maintain consistency across an application in the absence of existing coding standards.
  4. Built on test first principles. Unit and e2e tests are baked into the generators.
Against:
  1. Performance overall is mediocre. Initialising a new project or running tests for the first time can be very slow.
  2. Still in beta and past changes show they’re not afraid to move the goal posts by quite some margin.
  3. Currently no OOB support for cache busting in the webpack build.
  4. The inline help system isn’t good.
  5. Due to the development cadence it’s difficult to get answers to problems. Most answered questions on stackoverflow are long out of date.

ASP.NET Core Yeoman generators

If you’re looking at developing an Angular application using ASP.NET Core for the backend these generators are worth a look.

This is a great video by Steve Sanderson at NDC Sydney 2016 discussing their capability in some detail.

Community Starter Templates

These are a couple of github projects that provide a basic application along with some preconfigured tooling. Generally they’re going to provide the same bootstrapped project experience as you’ll get from the angular cli but in a slightly lighter touch template.

preboot/angular2-webpack

Low touch template with testing baked in and a solid README to get you going. As of this writing still being updated regularly.

mgechev/angular-seed

Gulp based build – not a bad thing! It’s an older project but it’s still being updated. Again the README is solid and there are a number of forked reference sites linked that may prove handy.