AngularJs with Webpack part 2: Angular Component and Webpack Loader

In my first post, I demonstrated how to use Webapck with AngularJs quickly and in the simplest possible way. You can read more in my previous article AngularJs with Webpack part 1. We will continue to build the same application and reference some things from the previous article so please get familiar to it or use it as a reference.

Today I am going to expand it with more advanced options. We will see how to use AngularJs components with a template in a separate HTML file, use CSS libraries (SASS), and make it all work with Webpack. We will make this work using Webapck Loader.

Now is time to expand it. As our application grows we want to make it as modular and as simple as possible. We use a template to create a dynamic page in combination with the controller. A template is our representation of data to the user. It will have bindings and presentation logic. We will use an HTML file. The controller is used to apply behavior and logic to our template. As this is the pattern that repeats trough whole application Angular offers us Components. Components combine template and controller in a new single reusable entity. “Everything that happens in component stays in the component” – because components have something called isolated scope so they won’t affect other parts of the application.

Main component

For our application, we will create the main component that will have the main layout of our web page. Later we will expand it with other components that will be more reusable and angular routing.

Create a new folder called main inside our app folder. Inside the ‘main’ folder, we will create two .js files for now. main.module.js were we will put our new module and main.component.js which will serve as our main component.

This is the new file tree:

Our main.component.js will look like this:
Function mainComponent returns controller and template. For now, let us keep it inline. Function mainComponentCtrl will be our controller for the main component. We will just set the title to “Main Component working!”.
This file structure allows us to separate components and then we can easily add them to modules, and add different modules to the main module of the angular application. so let us do that.

Main module

Let’s create main.module.js. The name is a little confusing. This is not the main module of our angular application that is used to bootstrap it. That one is in app.js. This main module will just be used as an example of a separate module and how to include them in the application.

But Angular allows us to inline it using dot syntax. That way is cleaner and simple.
We use export default phrase so this angular module will be available for import in other modules (including main app module) and it requires .name.
So let us do that.
Let’s change app.js (we can rename it to app.module.js but as it’s already set in Webpack let’s keep it this way).
app.js

We will keep for now old controller inside just to see it working together with the main component.
As you can see we imported our module and put it inside angular.module inside brackets. This will be an array of imports separated by a comma. That was the only thing we needed.

Use Component

So how to use component? Just edit index.html.
index.html

So to use component just use component name as HTML tags. Component name is mainComponent but angular requires small letters so we need to translate camelCase syntax to camel-case to make it work.

After all that just run npm start in the console.

Now we can use “mainComponent” anywhere inside the application. In this way, it is not reusable but this was only a simple example. This is the power of Angular component.

HTML Template

Let us extract the template from Angular component and put it in a separate HTML file.

Create a new file inside “main” folder called main.component.html

main.component.html

Now, change main.component.js
Replace:

Replace the template part with this line:

template: require('./main.component.html')

Only one change is required, to replace the inline code with a path to HTML template inside “require”.

But now Webpack complains. Our application is broken! We need loaders to read that HTML file!

Webpack Loaders

Webpack only understands JavaScript. When we use different file types Webpack is confused and breaks. Loaders allow Webpack to understand and convert other types of files. To use them we first need to download them as dependencies and add them to our project and Webpack config.

To make HTML files work with Webpack we will use html-loader.

First, install it:

npm install html-loader --save-dev

Now change the webpack.config.js file.
webpack.config.js

Loaders go inside “module” property of “module.exports” object. Here we added new property “rules” which takes an array of objects. Each object in the array has “test” and “use” properties. The “test” property has a value in form of file type associated with a loader we want to use and use property takes as value name of the loader as a string. Simplified: test all files that end with HTML and use html-loader on them.

We want to expand our application more. So we will use separate SASS files for our CSS. We could use plain CSS but with SASS we can see how loaders actually work

So, you would probably guess that we will need a CSS and SASS loaders and you would be right. But we will also need a style loader. Style loader will create style nodes from Js strings.

Install sass and loaders

We need to install node-sass so we can use SASS files and install required loader dependencies:

npm install node-sass --save-dev

npm install sass-loader --save-dev

npm install style-loader --save-dev

npm install css-loader --save-dev

Add seperate style file

Let us first create main.module.scss file in “main” folder and include it in our project inside main.module.js.

We just added main-container class to div and added some text to easily recognize changes.

Also, we need to include this new main.module.scss file inside main.module.js. using ‘require’.

main.module.js

Configure webpack

Our application is broken now. Because we added SASS file that can’t be understood by Weback. We already installed all the dependencies we need. Now just add them to webapc.config.js.

For .scss files, we will first use style-loader to compile them to CSS. Css-loader will then translate that CSS into JavaScript so it is understood by Webpack. In the end, style-loader will create style nodes from JavaScript strings.

Our application is running fine again.

As you can see our SASS has changed styles in “main.component” template and style-loader have added style to html file head tag.

But this will not satisfy us because we want to put all our CSS in a separate file and add Bootstrap to our project. To do that we will use Plugins.