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: []
})

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.

Obtaining Typescript Definition Files

Standard

typings or the types npm organisation?

In this post I’ll look at the current options available to us for managing the definition files (d.ts) in our typescript projects.

I recently started looking at the new features in typescript 2.0 and was surprised to find that tsd has been deprecated. The deprecation isn’t part of the 2.0 release as tsd is/was just external tooling but it quickly became part of my refresher that I thought I’d share here.

As a quick update tsd was a command line tool that allowed you to pull type definition files for external libraries (lodash, jquery etc) into your project.

I discovered we now have two options available to us that initially caused me some confusion as I wasn’t sure if they were related in some way. They’re not.

typings

The typings project is a community supported option hosted on github that has been the primary replacement for tsd. It allows you to pull in definition files from a number of sources and continues to be supported. It has a solid upgrade path if you’re moving a project from tsd.

View the README on the project repository for more info.

@types (organisation on npm)

The @types organisation on npm has been created by Microsoft as a response to the communities feedback that obtaining definition files has been troublesome. At the time of writing the organisation contains 2247 separate packages. Since this is a regular npm repository you’ll just install the definition files as regular npm packages using the @prefix for the org:

npm install @types\lodash.

The repository is populated from a publisher service that continues to pull the definitions from the DefinitelyTyped repo. You could use it for pulling into a private repo if required.

Going forward I think I’ll be using @types. However, the new angular-cli uses typings which is how I was introduced to it’s existence. It’ll be interesting to see if they continue to use typings or move over to using @types.

I’ll be publishing another post soon describing how to configure a new typescript project to use @types.

Further reading:

Microsoft Blog Post – The Future of Declaration Files

Azure Code Samples

Standard

We’re certainly not short of demo solutions and todo apps but I was pleased to receive an email today with details on the now comprehensive list of Azure code samples available for download here.

Of particular interest to me are the identity management and authentication samples I’ll be hooking into Dynamics CRM 2016 and of course anything node related will always get my attention.

What is __proto__ in JavaScript?

Standard

If nothing else it has an amusing name, it’s pronounced “dunder proto” due to the double underscore notation it borrows from python.

The __proto__ property is used to access the prototype chain for an object instance. Don’t know what a prototype chain is? Go take a look here.

So where does it come from? It gets created on any new instance during construction.  If construction is done using a constructor function i.e by using the new keyword var a = new Person() it will point to the prototype of the constructor function, in this instance Person.prototype.  If done using object literal notation var b = {} it will point to Object.prototype. Note that as everything in JavaScript is an object, all objects can follow their prototype chain back to Object.prototype

You can also gain access to the prototype using Object.getPrototypeOf(...). MDN provides more on this. You should give this a read if you haven’t already to understand the history of this property.

The following code demonstrates the setup of two very simple object literal and constructor function prototype chains.

//Object literal
var o = {};
o.__proto__ === Object.prototype; //true
o.prototype === undefined;   //true

//Constructor function
function Shape(){}
var circle = new Shape();

circle.__proto__ === Shape.prototype;   //true
circle.__proto__.__proto__ == Object.prototype; //true
Shape.__proto__ === Function.prototype;   //true

More reading.

I’ve already linked them above but as always the MDN docs are a good place to start.  There is a great stackoverflow post that has some really valuable insight amongst the many answers and comments.

Solving a failed npm install on the Raspberry Pi

Standard

TL;DR If you are struggling with npm install failing on a package you are convinced is no longer a dependency of your current package.json structure. Try clearing out your node_modules folder or take a look at the npm prune command.

I know this post is quite a long one but most of the content was created in realtime as I was working the problem. I’m a voracious note taker so figured I’d just write up my notes as a blog post as I went along.

I have a little express website running on my raspberry pi B+ from home. I deploy to this site using a post-receive git hook that deploys the master branch and runs npm install --production to ensure the latest dependencies are installed. Notice that I use the –production switch to ensure devDependencies are not installed.

After trying to access this site following a push I found the site to be unavailable. I use forever to maintain the node process so I checked the logs and noticed a number of errors indicating new dependencies had not been installed.

I ssh’d into the server and run npm install --production manually and saw that it was taking an unusually long time to complete eventually failing due to native module compilation failure.

Here are the new packages my latest commit has introduced:

  • dependencies
  • passport
  • passport-local
  • devDependencies
  • browser-sync
  • gulp
  • gulp-nodemon

As you can see, passport and passport-local are the only packages that should be installed. However, after I traced the failed module up the dependency tree shown below you can see that npm was trying to install browser-sync whose dependency graph relies on native modules.

bufferutil -> ws -> engine.io -> socket.io -> http-proxy -> foxy -> browser-sync

At this point I checked online to see if there were any known issues but only came up with this github issue which is old and closed.

Let’s see what the status of the --production switch is in the current npm docs

With the –production flag (or when the NODE_ENV environment variable is set to production), npm will not install modules listed in devDependencies.

That seems consistent with my understanding. So let’s make sure we’re on the latest version of npm and see if that fixes it.

My npm version (at the the time of posting) is 3.3.12, let’s update with the utter brain f*ck that is self updating software.

sudo npm install npm -g

The update has taken us to 3.6.0 but having tried to run npm install --production again I’m getting the same result with a failed compile.

So I know that the dependency causing the problem is browser-sync. Let’s confirm this by removing it from package.json. When I now run npm install it shouldn’t matter whether it does or doesn’t install devDependencies as the package causing the problem isn’t in either section.

To my surprise this still fails! OK npm install is clearly not just running through the package.json and installing the specified packages and their dependencies as I expected.

The next logical step (yes I know, many of you may have arrived at this point long ago) is to delete my node_modules folder and rerun npm install.

Success! Everything installs as required.

What’s going on? Well, it would seem that npm install doesn’t just install packages and dependencies defined in your package.json. Instead it sees your package.json as simply the top level in the dependency graph. Once it’s completed the install for all the packages in your package.json, it must then start enumerating all of the packages under node_modules and repeat the process for their package.json files.

This behaviour makes sense and more importantly for me would explain how I ended up with this problem. My git hook script does an npm install without the –production switch. After I’d fixed this up as part of my analysis of this issue I’d fixed the problem for future deployments but I’d left my node_modules folder in an invalid state because the failing module (browser-sync) was still in there.

Further reading on this problem shows there is an npm command called prune that will clear all dangling dependencies from your node_modules folder based on your current package.json. In fact we can do the following to clear out just our devDependencies, a common requirement if we’ve inadvertently installed them on the production box…as if!

npm prune --production

So, problem solved.  I hope this post has been useful or at least mildly entertaining for the more initiated out there.