Menu

Writing ES6 Ionic code with webpack

My history with JS Build tools

I remember the first time I came across a build system for my JS programs, it was quite a revelation... Wait, I can compile scss, minify my js code, lint, and run unit tests seamlessly with no extra effort? Add to that the ability to livereload my page and see the css\js changes I make without the hassle of reloading my webapp every time.

The first build tool I used was Grunt. I created my first build tasks, it was simply made to compile my scss files, run some lints and live reloading the web page on changes. It was all great, but when my app grown in size, my Grunt tasks started to get slow. The main reason for this was mainly because Grunt requires opening each file in the task flow, make the changes and write the file back to disk for the next step in the process.

Gulp to the rescue, when gulp came out it was kind of a game changer for me, since I was just started working with nodejs and the support of streams that allowed gulp to run my tasks wayyyy faster then Grunt. Gulp reads the file once, and then using node streams transforms the files in memory, and return the processed output to the next step.

Module bundling

When I started to get interested in SPA frameworks, and mainly with angularjs, it came to a point when my index.html file was looking something like:

Really fast it was a mess, so I started to look in to better ways to write my applications.

Module Bundlers, I was looking the web for solutions for this js files mess. Browserify and Requirejs was the first solid options I found and suddenly I could create only a single entry file for my entire Angular app, I could require files and plugins as needed from my main entry point and write modular webapps. Hurray!

Webpack

So it's all sounds good, why replacing Gulp + Browserify workflow ?

There are few things about webpack you need to understand, the first one is that webpack is much more opinionated. It assumes that your intent is to have some sort of entry file or files and you want to transform them and output to another location. This statement alone made my webpack.config much smaller in size compared to my Gulpfile.

Then, when it comes to bundling, webpack allows you to bundle not only js files, but also bundle your scss, hbs\jade and image files using the same bundle file. Webpack is smart enough to determine if its a small file it will simply inject the html with an inline style block. Or if the file is large it will minify it and serve it as normal css file. For images, it will transfer your images to a Base64 String and inject them directly.

Another cool feature from webpack is the ability to split bundles, then when you need them you can require them as if they exist and webpack will automatically load them during runtime. You can use ocLazyLoader with angular to avoid loading huge bundle files upfront.

The last thing I really loved about webpack is the webpack-dev-server, it allows really cool feature called hot module reloading, which means that when you make changes to a file, webpack will replace the changed module in memory and inject it to your app without the need to fully reload the page. Recently I was rewriting big module inside our app using react, with react-hot-loader by Dan Abramov. And I won't ever code again without it.

And the most amazing part, besides configuring webpack the only thing you need to added to your index.html as an asset is:

<script src="/dist/bundle.js"></script>

Webpack and Ionic workflow

So after hopefully you understand how webpack can improve your productivity and code scalability while improving performance, let's start to configure our Ionic app.

This guide assuming you already familiar with ionic basics and already installed the ionic cli.

We will create a blank ionic app using the ionic:

ionic start ionic-webpack blank
cd ionic-webpack

We will install webpack and webpack-dev-server, for the purposes of this tutorial I will install them globally, but you can install them locally to the project.

npm install webpack webpack-dev-server -g

Now we will install some webpack loaders, they are responsible for transforming our code. We will install babel-loader that will allow us to use ES6 syntax inside our ionic code.

The reason we install webpack to the project aswell is because extract-text-webpack-plugin requires some webpack modules, and it will fail saying: 'Cannot find module webpack/lib/removeAndDo', or other errors without installing webpack locally.

So, we done with all the boilerplate, let's start coding with webpack!

Writing modular ionic code

We will start with index.html file, we will remove 'app.js' script tag and add a single file named bundle.js

<script src="bundle.js"></script>

Then, we will remove the app.css link on index page and added ionic.app.css which will be the compiled version of our scss files.

<link href="ionic.app.css" rel="stylesheet">

We will leave ionic bundle files in the header, as well as the cordova.js import.
For this tutorial we will use angular as global variable, you can further modify your build and inject angular whenever needed.

To start, open www\js\app.js file with your favourite code editor.

We will start by importing our main scss file to the project in the top of the document, so that webpack will be able to process it:

import 'ionic.app.scss';

Now we can export our routing file to a different file. Create a new file named app.router.js in the main js directory, and add the next code:

Conclusion

Webpack allows us to bundle multiple js, html, and css files to a single bundle file.

It allows us to write es6 syntax with angular 1.X, that will later help you to migrate more easily to angular 2.

There are multiple strategies to build and organise your modules in angular, here I showed a small example of what you can do with webpack. You can take it much further with your apps.

Lately I've been looking into angular components architecture with the angular 1.5 .component() method, which helps you to define directives in a faster way. For me writing angular directives before was quite tedious work, so I used it mostly when I needed it. When started playing with React, creating components was so easy and it really made my code much more flexible and reusable. Taking this approach to angular is now much straightforward for me using .component(). Angular 2 embraces components as its core, writing your angular 1.x apps with this strategy in mind will help you transfer your existing code to angular 2 later.