I like to write down my notes while setup a Cordova based application with Webpack, AnuglarJS and Onsen UI using Babel for ES2015 support. It’s not my first Cordova project but I like to write down all the things I touched and thoughts I had so maybe next time I don’t have to dig it out all over again.
Basically I’d like to combine the following tools with the following motivation:
|Webpack + Babel||Would be nice to write ES2015 style classes, use friends like
|Onsen UI||Brilliant UI with many options and excellent performance.|
|AngularJS||As a simple enough binding engine to organize the UI and screen flow.|
Setting up Cordova and Webpack
# Create the app using Cordovas cli cordova create mcabc de.cschnack.mcabc mcabc cordova platform add android
Once that’s done I add cordova-plugin-webpack. It enables support for Webpack in Cordova apps and improves the overall workflow with features like: hot module reloading.
Following the instruction of the plugin page:
cordova plugin add cordova-plugin-webpack
- (a) + (b) create
- (c) create
srcfolder and move
- (d) let the the app point to the build result
To build and test it I just write
cordova build cordova run -- --livereload
Configure Babel for Webpack
To have support for ES2015 language features I need to configure Babel:
- (a) add Babel core, loader and preset in the
- (b) update Webpack configuration
preset-env does not yet support the spread-syntax for objects. To have that I also added
Once I called
npm install the additional dependencies are downloaded. Now the code under
Bootstrap AngularJS in Cordova/Webpack environment
Running AngularJS in a Webpack ES2015 transpiled context is something that can lead to confusion. AngularJS provides a dependency framework which kind of solves the same thing as modules do. I found some more plugins for Webpack to specifically take care of modules and AngularJS dependencies. However, as I’m not sure how those plugins work within the cordova-webpack-plugin environment and as they seem to favor AngularJS components - which I don’t - I’d like to work around that.
- (a) In
index.htmlI provide a ID to the HTML element. This is going to be our app element. As I need to wait for Cordova to initialize before I initialize AngularJS I do not set an
ng-apphere. I do that later in code
- (b) For first testing I added a binding for
testStringas part of the
- (c) I have to update
- (d) In
index.jsI make sure that first Cordova signals deviceready before AngularJS starts to work on DOM. Importing the
TestControllerhere registers the controller globally.
- (e) With
module.jsI make sure that no matter how often I import the module I only create one instance. Here the module configuration should go.
- (f) An example controller for the
<div ng-controller="TestController">of (b). Thanks to Webpack I can use ES2015 modules and import the configured module and create our AngularJS style controllers.
So, technically it works like this. However, AngularJS offers it’s own module system and a dependency injection mechanic. This feels of on top of the ES2015 modules but for now I just accept it as the price I have to pay to use the oldish AngularJS.
Integrate Onsen UI
Having AngularJS, Webpack, Babel and Cordova running I already have an environment to work with. With Onsen UI I add a pure HTML UI which simulates a good enough native look & feel.
Onsen UI comes with a core library and CSS. To make it run with AngularJS I have to load a driver called angularjs-onsen. To make it work in a webpacked environment I have to import it in a certain order.
- (a) I have to make sure the Onsen UI is loaded from the package into our
index.bundle.js. For that I simply import it in
- (b) This is part of a hackish solution to let the
angularjs-onsen-uidriver being able to find Onsen UI. Naturally having a dependency to a global variable is a big no no in module based environment. However, for the given context it’s okay.
- (c) I update the module creation by adding Onsen UI.
- (d) Here I import the AngularJS driver. Putting this into index.js makes sure that (b) is executed the driver is imported. This is part 2 of the hackish solution to get it run.
- (e) Load the Onsen UI CSS files. I do that by a simple import (notice the
'). To make CSS imports work I have to…
- (f) …add rules into
webpack.config.js. I make sure that Webpack is able to recognize CSS files and copies font-dependency into
www/import_fonts. To use this rules and also Onsen UI, I also have to…
- (g) …update the
onsenui, angularjs-onsenui, style-loader, css-loader and file-loader.
- (i)/(k) With all that I now can use the Onsen UI elements in our HTML files. I put the Onsen html files into
www/views/*so they are just normal Cordova resources. The controllers I put into
srcfolder so they are transpiled and packed.
Having all this I now have a nice enough environment to implement content into the app.
Run it and access console.log
Running the app using
cordova run -- --livereload the emulator starts automatically. The image at the bottom nicely shows livereload means. One can make a change in the source and thanks to all the stuff I did before it automatically refreshes content within the running app. Onsen UI and AngularJS work as they should.
This works with the emulator and with a device. On Android it is possible to access the log-output and inspect the entire application using Chrome. For that one simply has to simply do this:
From there it’s easy to connect to the running emulator or device.
If put all things together I have a nice list of feature:
- Modern ES2015-language features can be used
- Resulting app code is compatible with older devices
- Cordova and Onsen UI together offer a good user experience with a lot of flexibility
- Dependency management for libraries is under control of
- Livereload allows quick prototyping
- Babel checks for syntax errors