Thursday, January 24, 2019

Push Aurelia => Cordova Build

Now that we have access to the Cordova environment in our Aurelia project it is time to modify the build scripts to push the Aurelia project into the correct locations so that Cordova can build our project as a mobile deployment.

Cordova

Before we start pushing files around we really need to understand how the Cordova build environment works. Let's take a quick look at the root folder structure:

  • /hooks                       Cordova build hooks
  • /platforms                 Cordova platform files
  • /plugins                     Cordova plugin files
  • /res                            Resource files (images for different screen resolutions)
  • /www                        Project source files
The hooks folder is a repository for files that can "hook" into the build process. You can read more about it here.

The platforms folder contains a folder for each platform that in turn contain all the required files for a complete build for each platform. Files in this folder structure should not be edited because they are replaced by the build scripts during each build. Each platform folder contains folders and files specific to the specific platform. The android folder contains a complete android project that can be opened and debugged using Android Studio. The ios folder contains a complete xcode project that can be opened and debugged in XCode on a Mac. You will notice that each platform folder has a www folder. If you were developing the project as a stand alone project this is where you would actually do your code editing, but since we are pushing our code into these projects any changes you make here would be overwritten by our scripts.

The plugins folder is a repository for each plugin that you add to the Cordova project. Each plugin folder contains all the files needed to support the different platforms. Again, you should not make any changes to code in this folder. It is possible to author your own plugins. You can read more here.

The res folder contains a collection of various size images to support all the different screen resolution of mobile devices. You can read more about it here. This tool can help you build all the required images. 

The www folder is where you write your code for your Cordova project. It is the single code repository that gets pushed to all the platforms during the cordova build. This will be the destination for our aurelia build scripts. Again, do not manually edit files in this directory. Your changes will be lost during the next aurelia build!

Now that we have a basic understanding on the directory structure it is time to write some Aurelia build scripts. There are a couple of basic concepts to understand here. First, we want to push the files after the bundles are written. You may think that we could just use the copyFiles routine that we previously used, however, that task copies files before the bundler runs. Second, we always want to clean the destination directories before we copy our files into them. If we did not do that, any file that we remove or re-locate in the project would be left behind in the destination as an orphaned file. We always want the destination to be free of old artifacts.

Let's get started.

We will begin by adding a new task to the aurelia_project/tasks folder. We want to build a similar task to the copyFiles task but with some small differences.
  1. Open your code editor and add a new file called push-files.js to the aurelia_project/tasks folder.
  2. Cut and paste code from here into the new file and save.


  3. Open aurelia/project/tasks/build.js in your editor.
  4. Make the following changes and save.

  5. Open aurelia/project/tasks/watch.js in your editor.
  6. Make the following changes and save.


  7. Open aurelia_project/aurelia.json in your editor.
  8. Make the following changes and save.

OK, let's recap what we have just done.

We created a new task that reads instructions from the aurelia.json file. It behaves very much like the copyFiles task, except it executes a del task before it copies the source files to the intended destinations. As we add more resources and files to this push file task the del helps ensure that old and orphaned files are removed from the destinations as we remove or relocate them in our source code as we progress with our development and refactoring of the project.

We included our new push files task in the build task so that it runs immediately after building the bundles.

We also included our new push files task in the watch task, so that when a change in our source code  triggers a build in the Aurelia project, our new push files task gets executed to ensure the build paths are always up-to-date with our latest changes.

We added a bunch of sources and targets to the aurelia.json file to instruct our new task what to do.

The structure of the json node for our new task is very important. It contains a "sources" node and a "targets" node. The sources behaves exactly like the copyFiles task (I always try to be as consistent as possible with existing code).

The sources node is a json object that contains a key value pair for each file or folder that we want to push. It supports standard glob patterns. The key is the filename including the path from root of the resource we are pushing. The value is the receiving directory again referenced from the root.

The targets node is an array of destinations for our push task. Each destination is referenced from the root of our project. You will see that I have added the root www folder as well as a www folder for each platform we added to the Cordova project. The task will take each destination or target, add the receiving directory from sources and then push the files to this new location.

If we break this down to a math type of equation it would look like this:

  • "sources": { "f": "d" }, "targets": [ "a", "b" ]
would result in:

  • d/f  being copied to  a/d/f   and  b/d/f 
While it is not necessary to add each platform www folder to the targets list (every time you build the Cordova project the www folder gets copied), it is desirable if you have a project open in Android Studio or XCode for debugging. Adding these target destinations results in our Aurelia code changes automatically appearing in the Cordova projects without having to continually build the entire Cordova project ... sweet ... !

NOTE: Our new task only pushes the Aurelia project and associated resources to the Cordova project. If you make any changes to the Cordova project structure you would have to do a Cordova build to include the Cordova changes that you have made.

As we add more resources to our project we may elect to have some resources reside in the root directory instead of inside the client folder. There are many reasons for doing this. Sometimes it is because of logistical concerns, sometimes it is simply personal preference. For example, we will be adding Internationalization to our project and I like to keep the translation files in a separate folder called 'locales' in the root of the project. We could include this folder in our file push by simply adding "locales/**/*": "locales" to the sources node of the aurelia.json file.

NOTE: If you remove an entry from the aurelia.json file, the corresponding files will NOT be removed from the targets the next time the task runs because the task simply does not know about them anymore. You have to manually do housekeeping on the target directories in this scenario!

NOTE: When changes are made to core files outside the client directory (such as aurelia.json or any of the task files), the Aurelia file watcher will NOT pick them up. You must cancel the command prompt session and run the 'au run --watch' command to rebuild the Aurelia project and capture these changes.

OK, lets fire up the Aurelia app to test our additions.
  1. Open a command prompt.
  2. Run command 'nvm use 10.14.0'
  3. Run command 'npm install merge2 --save-dev' to install new library used in push-files.js
  4. Run command 'au run --watch'
  5. Open a file explorer to the root/www directory of our project.
  6. You should see our 'pushed' files and directories have appeared. 

  7. We should check each destination in our target list to ensure the files have arrived.



  8. You should see extra files that have been inserted by the cordova build process in each platform. We must ensure that we do not remove or copy any of these files because they are platform specific. We only want to push our Aurelia project files to these folders!

NOTE: If you are working on a Windows machine you will not be able to run the 'cordova build ios' command. This can only be done on a Mac (or on a Mac VM running on Windows). I have run the command on my Mac and copied the files back to my Windows machine for the purpose of obtaining the screen shot shown above. Your ios/www directory may be missing the Cordova injected files. Don't worry about this if you are running on a Windows machine.   

We should now have a fully automated push from Aurelia to Cordova whenever we start up the Aurelia run process or whenever we make any changes to the Aurelia client project when the Aurelia run process is active. Let's test our solution.
  1. Run command 'au run --watch'
  2. Open a new (second) command prompt in the root of our project.
  3. Run command 'nvm use 10.14.0'
  4. Run command 'cd www'
  5. Run command 'cordova run browser'
  6. You should see the browser open to the Aurelia 'Hello World' page. Remember we disabled the splash screen for browsers.

  7. Run command 'cordova run android'
  8. You should see the emulator open and the Cordova splash screen for a couple of seconds and then the Aurelia 'Hello World' should appear ... magic ...


If you have a MAC you can follow the same process and should see the same results!

NOTE: You will get an error if you try to run the 'cordova ... ' commands from the project root. Node finds our cordova.js shim and tries to execute it instead of running the Cordova build script. (I am still researching to determine if this behavior can be changed ...). An easy fix is to change directory to the www folder (any will do) and run the Cordova commands from there!

Congratulations! We have successfully integrated our Aurelia project into a Cordova project! Go ahead and open up your editor, open a command prompt and au run, then make some changes to the Hello World screen and save your changes. Open Android Studio and run the app ... You should see your changes in the emulator!

You can even go ahead and deploy the app to an Android or IOS device ... awesome ...

Android Studio has a built in file watcher that auto rebuilds the app, however at the time of writing this, the watcher does not see our pushed file changes, therefore you will need to re-start the app to see your changes. I'm hoping that this feature will be modified in the future to pick up our changes.

XCode also requires you to re-launch to see the changes. However this is a small inconvenience when we consider the level of integration we have achieved so far!

In the next blog we will deal with adding resources to our project for mobile builds



No comments:

Post a Comment