About
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.
Clients stack
Basically I’d like to combine the following tools with the following motivation:
Tool | Motivation |
---|---|
Cordova | I like to use JavaScript and it’s tools. For me it’s the best compromise in many ways (performance, code quality, community, tools, libraries, fun). |
Webpack + Babel | Would be nice to write ES2015 style classes, use friends like [...someArray] and modules but still run it on older JS engines. |
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
As a very first step I create a new Cordova app and integrate Webpack with babel. This allows me to write modern JavaScript which is a must for me.
# 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
webpack.config.js
- (c) create
src
folder and moveindex.js
into it - (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
package.js
- (b) update Webpack configuration
The preset-env
does not yet support the spread-syntax for objects. To have that I also added @babel/plugin-proposal-object-rest-spread
.
Once I called npm install
the additional dependencies are downloaded. Now the code under src/*
can contain new language features. Thanks to Babel they are transpiled to classic JavaScript:
Love it!
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.html
I 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 anng-app
here. I do that later in code - (b) For first testing I added a binding for
testString
as part of theng-Controller="TestController"
- (c) I have to update
index.js
and addedmodule.js
theTestController.js
.
- (d) In
index.js
I make sure that first Cordova signals deviceready before AngularJS starts to work on DOM. Importing theTestController
here registers the controller globally. - (e) With
module.js
I 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 inmodule.js
. - (b) This is part of a hackish solution to let the
angularjs-onsen-ui
driver 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
"
instead of'
). 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 intowww/import_fonts
. To use this rules and also Onsen UI, I also have to… - (g) …update the
package.json
and added: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 intosrc
folder 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.
Final result
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
npm
andpackage.json
- Livereload allows quick prototyping
- Babel checks for syntax errors