Sunday, December 23, 2018

Mobile Support - Cordova

Now that we have a stable client / server framework configured in our development environment, it is time to add mobile support. Cordova (or Phonegap as it was previously called) is a perfect choice for this. It provides a collection of hardware interfaces for most devices as well as all the required build scripts for Android, IOS and Windows. I will be focusing on Android and IOS but you could certainly add others if your needs require them.

Cordova

First we will install the Cordova CLI.

  1. Open a command prompt in the root of our project folder.
  2. Run command 'nvm use 10.14.0'
  3. Run command 'npm install cordova -g'

Just like the Aurelia CLI, we want to install the Cordova CLI as a global package. This is necessary to manage the project structure.

Now it is time to create our skeleton Cordova project.

NOTE: For the remainder of this blog I will assume you already have a command prompt open in the root project directory and have run the 'nvm use' command.

  1. Run command 'cordova create  applewood com.your_name_here.applewood  Applewood'

The parameters for the create command are discussed in detail here. The parameters are not critical to the project success. They are saved in a configuration file and may be edited in the future. The create command builds a skeleton cordova project in a sub directory named in the first parameter. If you have a look at the root director of our project you will see the new applewood folder.

Next, we want to merge our skeleton cordova project into our master project.
  1. Open the root project in a file explorer.
  2. Open the new applewood directory in a second file explorer.
  3. Copy all sub directories from the applewood directory to the root directory
  4. Copy .npmignore from the applewood directory to the root directory.
  5. Copy config.xml from the applewood directory to the root directory.
  6. DO NOT COPY package.json file! This would overwrite your existing package.json file and that would be catastrophic because you would lose all the root project package information. 
  7. Delete the applewood folder from our project.
Our root project folder should look like this:


Platforms

Next we need to add our required cordova platforms to our project.
  1. Run command 'cordova platform add browser' 

  2. Run command 'cordova platform add android'

  3. Run command 'cordova platform add ios'

Note: It is important to include the browser platform. This platform creates a shim file that we will use to simulate a mobile environment during the development process. This is useful to test our code as well as avoid the pesky and annoying browser errors that are typically associated with developing mobile code in the browser on your desktop. A little more about this later. 

Plugins

Next we need to add a couple of cordova plugins for basic device support and a splash screen.
  1. Run command 'cordova plugin add cordova-plugin-whitelist'
  2. Run command 'cordova plugin add cordova-plugin-device'
  3. Run command 'cordova plugin add cordova-plugin-splashscreen'
If you desire any other plugins you could add them now. You can always add plugins at any time during the development cycle.

Test Project in Browser

We should be able to test run the cordova project now.
  1. Run command 'cordova run browser'

A new browser should open displaying the default cordova project


You should also open the Dev Tools (right click / Inspect or press F12) and make sure there are no errors reported in the console.

Now that we have a running cordova project we need to do a little housekeeping.

Source Control

When you add or remove platforms or plugins to the project, the configuration information is saved in a file called config.xml in the root of your project. Just like the NODE packages that are saved in the node_modules folder, we are not concerned about including the Cordova platform or Plugin packages in our projects source control. These are files required by the build scripts to support the various platforms and hardware we are targeting during deployment.

NOTE: The platforms and plugins folders contain content that intentionally is not included in the source code repository. This means that when you clone a project from the repository into your working folder you must populate these folders before you can use the project. This is done by opening a command prompt in the working folder and running a command to fetch and populate the folder with the required packages. For our project do the following:
  1. Open command prompt in root of the project folder
  2. Run command 'nvm use 10.14.0'
  3. Run command 'cordova prepare'
You must do this every time you clone a project from the repository to a working directory!

We need to modify the .gitignore file to exclude these folders from our source control. We also want to exclude the www folder from our source control. The www folder contains a copy of the client code for our project and is dynamic in nature, which means it gets rebuilt after every change to the client code. A little more about this later.
  1. Add a new file called README.md to the www folder. (You can copy this file from the Smoke House Project www folder if you wish)
  2. Open .gitignore file in your code editor.
  3. Add a line to exclude the platforms directory.
  4. Add a line to exclude the plugins directory.
  5. Add a line to exclude the www directory contents.
  6. Add a line to include www/README.md file.


NOTE: We use the README.md file as a placeholder in the www folder. It tells GIT to save the www folder as part of our project. If we do not add this placeholder, GIT automatically will remove the www folder from our source control. Cordova checks to see if the www folder exists to determine if this project is a valid cordova project. If the folder is missing the Cordova CLI will report that this is NOT a cordova project and you will not be able to execute and Cordova CLI commands from the command prompt.

Android Project

One of the nice features of the Cordova CLI is that it creates an Android project. You can open that project in Android Studio (assuming you have it installed).

If you do not have Android Studio installed I highly recommend you install it and get a starter project configured and running on your computer before trying to run this project. You can do this on either a Windows or MAC computer.
  1. Open Android Studio.

  2. Select 'Open an existing Android Studio Project'

  3. Select '\platforms\android' from your working project root.

  4. If you see the Android Gradle Plugin Update - DO NOT UPDATE! - Select 'Don't remind me again for this project'. The cordova CLI build scripts use a specific gradle version and upgrading will cause multiple build failures! 
  5. Run the application. Click the green arrow in the toolbar. You may have to configure and select a device on the next screen depending on your project settings.

  6. The Android emulator should start and present our project.

If you have all of the above configured and working we should be able to build and launch the Android project from our command prompt.
  1. Run command 'cordova run android'
The project will build and the same emulator should launch!

IOS Project

Now it is time to switch gears. Unfortunately you cannot build or run an IOS application on a Windows machine. So I have swiveled my chair and have picked up this blog on my MAC.

The Cordova CLI also builds a valid XCODE project. Pretty slick!

If you do not have XCODE installed I highly recommend that you install it now and go through the process of configuring and running a sample project before attempting to run this project.

NOTE: You will need to set up code signing. Please read this.

The first thing we need to do is GIT the project from our source repository and install all of the required packages from Node and Cordova. We also need to ensure we have our development environment installed and configured.

  1. Clone your local repository to a working folder.
  2. Open a terminal window (command prompt) in the root of the working folder.
  3. Run command 'nvm use 10.14.0'

  4. Run command 'npm install aurelia-cli -g'

  5. Run command 'npm install cordova -g'

  6. Run command 'npm install'

  7. CD into the server folder
  8. Run command 'npm install'

  9. CD back to the root
  10. Run command 'cordova prepare'

NOTE: You may see different content in the screens when preforming some of these instructions. The installers add packages based on existing content, updated content and other factors. This is normal. Remember, I may have previously installed packages before writing this blog ....

This is the exact same process we used on our Windows machine ... pretty sweet. Note that NVM automatically elevates the users permissions in the active terminal so that the SUDO command is not required!

We will be adding some custom scripts a little later to automate some of this process to simplify our efforts.

At this point in time we should have an exact replica of our project from our Windows machine with the exception of the installed packages. The NPM installer and Cordova CLI install packages specific to the environment or machine where the project resides. So all of the platform specific 'stuff' is encapsulated and we don't have to worry about it. Again, pretty sweet ....

We should test the project to ensure it runs. 

NOTE:  At this point in time we actually have two separate projects installed even though they both reside in the root directory.  We have an Aurelia skeleton project and a Cordova skeleton project. We will merge these projects in my next blog.

Before we can start up the Aurelia project we must make one small adjustment in the server/config/config.dev.js file. The config.host must be set to the IP of this computer. This setting is used by the Express server that hosts the WEB API for our project.
  1. Open server/config/config.dev.js in your code editor.
  2. Change config.host = your_ip

  3. Save your changes
  4. Go back to command prompt
  5. Run command 'au run --watch --server'
    Add caption
  6. Open a browser to 'localhost:9000'

So far so good. We have the Aurelia project running in a browser. Lets see if the Cordova project runs. Don't forget to terminate the currently running host servers in the command prompt.
  1. Press [CONTROL][C] to terminate host processes.
  2. Run command 'cordova run browser'

  3. A browser should open showing the Cordova app

Now its time to open our project in XCODE.
  1. Open XCODE

  2. Select "Open another project ..."

  3. Select platforms/ios from the root of your working directory
  4. Select the RUN button

  5. The cordova skeleton project should open in an IOS Simulator 

Now we can test the build from the command prompt.
  1. Run command 'cordova run ios'

  2. Followed by pages of command output ....

  3. The cordova skeleton project should open in a simulator.

Now we have a skeleton Aurelia project and a skeleton Cordova project co-existing in a common project that is saved in our local GIT repository and can be cloned to both a Windows machine and a MAC. Both projects can be launched from a command line on both machines as well as edited using a common code editor on both machines. The cordova mobile projects can also be opened and edited in both Android Studio and XCode.

I think it's time for a beer! My next blog will be dealing with merging these two projects together. We are well on our way to having a simple yet flexible code base that can be deployed to multiple environments.

Wednesday, December 12, 2018

Client / Server Modification

Now that we have our Aurelia skeleton project all set up and working it is time to start making our modifications to satisfy the project goals.

Almost every application I have worked on in the last 10 years has used a basic Client / Server pattern. I want to modify the skeleton project to include the server portion. This is not necessary for the success of this project, it is more of a personal choice. I like to keep all my bits and pieces together when developing a project so I don't have to go chasing after them when I am trying to fix a bug a year or two down the road. I can simply git the project from my repository and fire it up in my development environment ... everything is there and ready to go.

Client Server

First, I want to rename the "src" folder in the skeleton project. This is the folder where you will add all the code that gets included in the client portion of the app. I like to call it "client" to make it perfectly clear that this folder is the Client portion of the application. Again, this is a personal choice and it is not necessary for a successful project.

NOTE: I will be modifying some files based on my decisions to make the changes outlined here. If you do not want to make these changes you may have to modify other files to support your preferences. I suggest you make these changes to ensure a successful project. 

  1. Rename the src folder to client
  2. Open aurelia.json file located in the aurelia_project folder in your code editor
  3. Locate all the "src" instances and change them to "client". There should be 5 in total at the following locations:
    1. transpiler.source
    2. markupProcessor.source
    3. cssProcessor.source
    4. jsonProcessor.source
    5. paths.root
The changes should look like this


Save your changes and make sure the project still runs.
  1. Open a command prompt in the project folder.
  2. Run command 'nvm use 10.14.0'
  3. Run command 'au run --watch'
The CLI should build the project and then launch a server hosting the project.


Open a chrome browser and browse to http://localhost:9000 and you should see the Hello World message.


Right click inside the browser window and chose [Inspect] to open the Chrome Dev Tools window. If you have never used Dev Tools before this will quickly become your new best friend. Check the console to make sure we don't have any reported errors.



Your window should look like the above image. Good news, everything is still working.

NOTE: By adding the '--watch' flag to the 'au run' command we are instructing the CLI to watch for file changes that we make in our editor and then reload the application in the chrome browser using a module called BrowserSync. A little more about this later.

We need to make one more change to the .gitignore file. This file instructs GIT, our source control, to not include certain files or directories in our project source history and data store.

  1. Open .gitignore in your code editor.
  2. Find the "/src/" occurrences and change them to "/client/"
  3. Save your changes.


Server


Next we want to add a new directory called 'server' to the project directory. This folder will hold all of our server code. The server I will be using is a simple Web API that hosts a Restful Data Service for our application. We will explore that a little later.




You can develop your own server code in the server folder or you can copy the server code from The Smoke House Project / Applewood / Server to your new server folder. My server code has a file called app.js. This is the main file that contains the code to start the web server. You can launch the server in a command prompt by running the command 'node app.js'

It is important to understand that the server folder is really a stand alone node project that has it's own package.json file and requires it's own runtime environment which is controlled by the nvm. It also requires us to run 'npm install' to download the node packages into a node_modules folder inside the server folder (that is not saved in the repository) ... just like our main client project.

Lets install the node modules and test the server code to ensure it runs.
  1. Open a command prompt in the server folder.
  2. Run command 'nvm use 10.14.0'
  3. Run command 'npm install'


NOTE: You can usually safely ignore the npm warnings. The reported vulnerability above does not have a fix at this point in time, however it can also be safely ignored. It is for a package we use called njwt. See the report below. Read this if you want to learn more about npm audit fix. 



NOTE: My project code requires a MongoDb server to be running and available to your project. If you don't have one available, take a moment now to install one locally. Consult the README file in the server folder to configure the server to use your DB.

Now we need to configure the server connections before we can start it up.
  1. Open server/config/config.dev in your editor
  2. Change config.host = 'your_ip'
  3. Change config.mongo.connectionstring = 'mongodb://your_mongo_server/Applewood'


Now start up the server
  1. Open a command prompt in the server directory
  2. Run command 'nvm use 10.14.0'
  3. Run command 'node app.js'
We should now see our web api server running


Auto Start Server

The Aurelia CLI uses gulp to automate runtime tasks. It can launch the client development server, watch files for changes, copy files to folders, refresh the browser and lots of other tasks.

Have a look in the aurelia_project folder. There is a folder called tasks. This folder contains all the gulp tasks that are controlled by the CLI.

I have a file in the server directory called launch.js This file contains a gulp task to start the web api server and watch it's files for changes. When it sees a change it will re-start the web server. This is an awesome feature to have when developing your code.

So now I want to add a flag to the 'au run' command so that we can auto start our server when we start the client. Kinda makes sense. The client needs the server so it has data to use. As we make changes to the client code, the aurelia tasks take care of refreshing the browser (client) and if we jump over to the server code our new task will take care of refreshing the server when we make changes.

  1. Open aurelia_project/tasks/run.js in the editor.
  2. Add a reference to our launch file

  3. Add the following code
Now we can launch our server when we run our client with a CLI parameter '--server'.

  1. Open a command prompt in the root of ur project.
  2. Run command 'nvm use 10.14.0'
  3. Run command 'au run --watch --server'


You can see that the web server has started.




Wednesday, December 5, 2018

JavaScript Framework - Aurelia

Now that we have our development environment all set up and ready to go it is time to create the root of the project which is the JavaScript framework. The framework is the bones of our application.

Because we want portability and the ability to run our app on a mobile device we need a framework that supports a Single Page Application or SPA. This is important in a mobile app, because the app is running in a headless browser and there is no way to navigate from page to page like a traditional web application. Our desktop application will also run the app in a headless browser. This is the core concept that gives us maximum portability.

Why Aurelia

My decision to use Aurelia as my core framework was not made easily. There are lots of other frameworks out there (and I really don't want to debate which is better in this blog) and I have used most of them in my career.

Aurelia provided me with most of my wish list, based on my concept, for this project. It has a relatively easy learning curve and it's design is very unobtrusive and flexible allowing me to manipulate it in certain areas to benefit this project. You can read about it's benefits and features here.

The CLI

Aurelia has a module called CLI or Command Line Interface. It is used to set up a basic Aurelia project and has several command lines options or choices for configuring the project. It is also used to start the development run time environment as well as a few other useful features.

NOTE: The remainder of this blog is a step by step tutorial to actually build The Smoke House Project ... All instructions are based on a new empty code repository and  it's associated working project directory. Do not perform these steps in a cloned copy of the existing Smoke House Project!

Let's create the bare bones or skeleton project in our new working directory now.
  1. Open a command prompt in your project directory.
  2. Run command 'nvm use 10.14.0'
  3. Run command 'npm install aurelia-cli -g'
This makes sure we are using the correct version of node for our project. Then we install the Aurelia CLI using NPM with a global flag. This allows us to run Aurelia CLI to create our project and then start it in the future.

We are using the Node Package Manager (NPM) to install node packages and maintain the package.json file for our project. You can read more about it here.

NOTE: Because we used the "-g" (global) flag the NPM installed the Aurelia CLI into the root or host node folder and NOT your project folder. NVM manages this folder and installs the required version of node that you requested with the 'nvm use ...' command. This keeps all of the Node specifics out of your project but makes them available to your project folder ... hope that makes sense! So if you check your project folder now it will still be empty but you should be able to run the command 'au' and the Aurelia CLI welcome message should appear.

Now that we have the CLI installed globally (for this version of node) we can create our new project.
  1. Open a command prompt in the project folder.
  2. Run command 'nvm use 10.14.0'
  3. Run command 'au new applewood --here'
This will start a wizard which will ask you to make project choices. "applewood" is the name of our project and the "--here" flag tells the wizard to build the project in the current directory. This is important as I will be customizing some scripts based on this choice!

Answer the questions with the following answers to get the same project structure as I am using:



Choose option 2 because Electron uses RequireJS so we want the same module loader in our project.

NOTE: You may see some different questions or they may appear in different orders based on the version of Aurelia's CLI that is installed. The questions presented here should be answered with my answers, if you see others use your best judgement!



If this question is not asked, Aurelia is automatically using the "Custom" option so just move on.


We will be using a Javascipt platform. I may build a .NET platform in the future.


We will be using Javascript ESNEXT. I may build a TypeScript project in the future.


Choose the default. It affords us maximum flexibility.


I am using LESS in this project. It is a personal choice.


I am using Karma in this project. It is a personal choice.


I am not doing any integration testing. It is a personal choice.


I am using Visual Studio Code. It is a personal choice.


The wizard is ready to create our new project. You may see a warning notice. Our directory should be empty but there is a hidden folder containing the GIT information. Go ahead and chose 1 to create the project skeleton.


Now go ahead and install the project dependencies. The wizard is using NPM in the background to download and install all the required dependencies. You can see a list of them in the package.json file after the wizard is complete. Be patient - Depending on your internet speed this process may take a bit of time!

Our skeleton project is now complete and ready to use. Please note that if you have deviated from my choices you may have to make additional modifications to your code to make this project successful!

Your project directory should now look like the following:


Take note of the "node_modules" folder. This is where all the project specific node packages are installed by NPM.

NOTE: Certain folders like the "node_modules" contain content that intentionally is not included in the source code repository. This means that when you clone a project from the repository into your working folder you must populate the folders like "node_modules" before you can use the project. This is done by opening a command prompt in the working folder and running a command to fetch and populate the folder with the required packages. For our project do the following:

  1. Open command prompt in root of the project folder
  2. Run command 'nvm use 10.14.0'
  3. Run command 'npm install'
You must do this every time you clone a project form the repository to a working directory!