How I Use Angular 2 with Webpack: Sample Application

Reading time: 5 minutes

A disclaimer: I’m not claiming to be an expert here and I’m open to any corrections or input from everyone; this is just what’s worked for me so far. Please enjoy!

In my previous posts, I showed how I’ve been setting up my Angular 2 projects with Webpack. I took you through each component starting with the dependencies and scripts to run through NPM, then moving to setting up things like typings, linting, and the compiler for TypeScript. I also showed how to set up Karma for testing with Jasmine before detailing how to configure Webpack for development, testing, and production (sort of).

The topics in the series are:

  1. Directory Structure
  2. Node Modules & NPM Configuration
  3. Typings
  4. Code Linting
  5. TypeScript Configuration
  6. Karma Configuration
  7. Webpack Configuration
  8. Sample Application

Now with all those pieces laid out, I just wanted to throw together a very small sample app to show how it all runs.

The project is on GitHub at https://github.com/gonzofish/ng2-tutorial-webpack. There you’ll also see my versions of the rest of the files talked about in this series. 

A Sampling of Developing Angular 2 with Webpack

The application we’ll build is just going to be a text box to type messages into, a submit button, and a list that tracks all the messages entered. Like I said, we’re not going to be setting the world on fire, but trying to understand how these pieces work together.

Testing

I’m a big proponent of unit testing first, so let’s start there. Here are the (very) high-level functionality we need our application to do:

  • Take input from a text box
  • React to clicking a submit button and store the text in the text box
  • Display the list of messages entered into the text box.

These all can be accomplished using two data structures (an array of strings for the messages and a string for the new message) and one function (to add new messages).

Running the Tests

Running the tests should be relatively painless. All of the setup is done and there’s an NPM script/task to run them (npm test). The only catch is that the Karma set up specified Chrome and PhantomJS2 as browsers. To only use one of these you could go into karma.conf.js and remove the other or you can create another NPM task.

Since I like to run my tests in PhantomJS until I hit a tough bug, I opted to add two more tasks to my package.json:

And instead of running npm test I run npm run test:headless (for command line testing) or npm run test:watch (for in-Chrome testing). Again, relatively painless. I just let one of those tasks run as I write my test and application code, checking as I go. If I get failed tests I know something in my application code is wonky.

Component Testing Setup

The first thing to do is pull in all the testing dependencies and then our AppComponent (which we’ll start developing in a second):

To test a component in Angular 2 can be a little awkward (as of 2.0.0-beta.11). Angular provides a test component builder which will–you guessed it–build our component for testing. It can do this asynchronously, through it’s createAsync method, which returns a Promise. I created a utility function called createComponent to do so:

The utility function takes a callback function (callback) as its only argument; this callback is where we can do our actual testing. We tell injectAsync to inject the TestComponentBuilder and then use it to asynchronously create an instance of AppComponent, which is then passed into the callback function.

Writing the Application with Unit Tests

Now we can actually write some tests. The first tests check that our component has the required data structures:

Now we can actually write some application code to satisfy those tests! We need two files, though, the bootstrap.ts and a component to test. The first file, bootstrap.ts, does what it says and bootstrap’s the application (it’s located at src/app/scripts/):

All this code does is pull in Angular’s bootstrap function and the AppComponent (below) and bootstrap’s our application using AppComponent as the starting point.

The component file is app.component.ts and is located in src/app/scripts/components/app/.

If you’re unfamiliar, here’s a quick summation of the above code:

  1. Import two classes from Angular
    1. Component: a decorator for creating components
    2. ViewEncapsulation: used to tell the component not to augment CSS classes for component-level specificity
  2. Import the main CSS styling and the HTML template we’ll use
  3. Create the component:
    1. Use ViewEncapsulation.None (as described above)
    2. Make the markup for this component be <my-app></my-app>
    3. Use the imported styles
    4. Use the imported template

Since @Component is a decorator, the class that it is decorating, AppComponent, is the component’s class. As you can see, it provides a string array for the messages and a string for adding a new message. You’ll need to add the main.scss (put it in src/app/styles) and app.component.html (put it in src/app/scripts/components/app) files for the tests to work. This satisfied our tests, so we can move on.

Adding a message is simple enough. We want to add the value of newMessage to the messages array when there is a value and then we clear out that value (so that our text input is cleared out when a value is added).

By doing our tests first, the code for this function is very minimal (it also helps that this is an overly-simplified application). And now that we have tests, we can move on to live-testing the application through the webpack-dev-server!

The final app.component.ts looks like this and I’m sure it blows your mind:

Developing with the Webpack Dev Server

We have 5 passing unit tests that describe the business logic of our application. We now need some real HTML to see this puppy in action. As the previous entries described, we need a pretty minimal HTML file (located at src/app/index.html):

Thanks to the HTML plugin, we need almost no markup. The only thing out of the ordinary here is the <my-app>Loading</my-app> line which uses the markup we prescribed in the previous section and puts a “Loading” placeholder until the app loads (you should almost never see this in an application this small).

For now just put <h1>Hello, Hamburger!</h1> in src/app/scripts/components/app/app.component.html to get something visual in our app. To see this in action, we just run npm start (the task in package.json). You should see something similar to the following if you got to http://localhost:8080/webpack-dev-server/:

The first pass at a visual app
The first pass at a visual app
You’ll notice my app is styled, which is all described in src/app/styles/main.scss. For your reference, here’s what my main.scss looks like:

Now we can some markup to app.component.html to get it working with AppComponent.

All we have here is a form that calls AppComponent‘s addMessage method on submit, AppComponent‘s newMessage variable is banana-in-a-box’d on the text input, and the message array is looped through for display below the form. The resulting page looks like the following:

The Message List without messages
The Message List without messages
As we type messages and submit, the list should grow, just like we wanted it to! Hurray!

The Message List with messages
The Message List with messages

And That’s It!

I haven’t really delved into the distribution/production side of things just yet, but will add a post in the future when I have.

Thank you so much for reading these articles. As always, feedback is appreciated and critiques are welcomed. I started out doing this for myself and hoped others my also get something out of it, so I hope you did.

Leave a Comment

Your email address will not be published. Required fields are marked *