Tuesday, January 8, 2019

Merge Cordova => Aurelia

Now that I've had a couple of beers and a much needed break it is time to jump into the fun stuff!

First we need to do a little research and understand how our two projects perform builds and where resources are located. Our mission is to modify some of the build scripts so that each project gets populated with the required files automatically when project resources are changed or modified, either by us in the editor or by the project's build scripts being executed by the CLI.

AURELIA

The Aurelia project is a SPA. It uses some build scripts to bundle up all your internal javascript, css, html, and resource files into a single file called app-bundle.js. It also uses an auto tracer to scan your code and bundle all the required resources (node packages) into a file called vendor-bundle.js. These two files are located in the scripts folder in the root of our project. The vendor bundle is added to the index.html file using a <script> tag. The app bundle is auto inserted into the document header by the vendor bundle. This provides a nice simple and clean way to deliver our SPA to a client. It also works very nicely with our Cordova project.

If any of you have ever worked on a Hybrid Mobile project in Cordova you will probably know about a very annoying little issue that always pops up in a new project. The Cordova framework is injected into our project by using a <script> tag in the index.html page ... just like Aurelia does. Since we are editing and testing our SPA in a browser outside of the Cordova environment we are constantly "reminded" by an error message in the console that the cordova.js file cannot be found. Secondly, the entire Cordova framework is not available during the development process. We used to deal with this by commenting out the script tag during desktop development and then adding it back in for mobile debugging in XCode or Android Studio ... not a very good solution!

The good news is that Cordova has a browser platform that can be included during desktop development that solves this problem and gives you access to the Cordova framework on your desktop during development ... sweet ... !

So let's start by adding the Cordova framework to our Aurelia project.
  1. Open the index.html file in your editor.
  2. Add  <script type="text/javascript" src="cordova.js"></script> directly below the <body ... > tag.

  3. Open a command prompt in the root of your project.
  4. Run command 'nvm use 10.14.0'
  5. Run command 'au run --watch'
  6. Open a browser to 'localhost:9000'
  7. Open the Dev Tools (inspect) and check the console.
  8. You will observer the following error:

Now lets fix this problem. We need to add the cordova.js and the cordova_plugins.js files to the root of our project. These files are auto generated by the Cordova CLI during a build event based on the current platform. Normally these files are NOT included in the project because they are subject to change based on environmental configuration. So we need to indulge in a bit of the age old "Chicken and Egg" scenario here. We will use an Aurelia build script to copy the Cordova files to our project root during an Aurelia build event BUT we will not include these files when we push our project files back to the Cordova file structure ... I'm getting a little ahead of myself here, but it is necessary to understand this process. We will address pushing our project files to the Cordova project in the next steps ...

OK, first we need to ensure the files we need have been created by Cordova CLI.
  1. Run command 'cordova prepare'
  2. You should see the platforms and plugins directories in the root of the project
  3. Open a file explorer to 'platforms\browser\www' directory.
You should see the cordova.js and cordova_plugins.js files. These are the files we need to copy back to the root of our project. We will do that by using a built in feature of the Aurelia build script.

NOTE: It is worth a mention here about the mysterious www folder that keeps appearing at various places in the Cordova project. This is a source of great confusion to developers and has been written about and documented extensively. You can read about it here. In a nutshell ... you create and edit your Cordova project files (your SPA) in the root/www folder. During Cordova build events these files are copied to the platform/www folders and then the build uses the platform specific folders to build each platform. You should NOT edit any files in the platform directory ... these are reserved for dynamic builds ... any editing you make there will be lost during the next build! ... simple once you understand how Cordova builds it's projects ...

There is a small problem running the Cordova files in the browser that we must address. When Cordova builds the platform specific files it performs some platform specific modifications to the package files that it uses as it's base. The base files are located in the platforms and plugins folders in the project root. The resulting build files are also located in these folders but reside at very specific directory levels. This all gets a little confusing but necessary because the generated files contain path specific requires to ensure all files needed by a platform get loaded for the specific platform. What all this means is we need to ensure we copy the correct file set to our project during the Aurelia build. Remember, these files are only used by our project for development and debugging. The Cordova build generates it's own files for the packaging and deployment of our app.

If you are totally confused at this point don't worry. Just follow the next instructions which will get the correct files into the correct locations and everything will work and hopefully will make sense ...

Now we can add instructions to copy these files to the project root/scripts directory instead of the root directory.. I have chosen this directory because it holds the Aurelia generated files therefore it is a logical place to store the Cordova generated files. Remember, do not edit these files because they get replaced during builds.

The reason we cannot copy the files to the root is because they contain path specific includes that will ultimately load the wrong support files if we run them from the root folder. We will fix this by including all of the required support files in a correct hierarchy inside the scripts folder.
  1. Open 'aurelia_project/aurelia.json' file in your editor
  2. Under the 'build:loader' node add a new node 'build:copyFiles'
  3. Add "platforms/browser/www/cordova*.js": "scripts"
  4. Add "platforms/browser/www/plugins/**/*.js": "scripts/plugins"

  5. Save the changes.
  6. Run command 'au run --watch'
  7. The two Cordova files and the plugins directory should appear in the scripts folder

So far so good. Every time Aurelia builds we will get the required Cordova file set injected into our project. A nice little bonus of using the Aurelia build to preform this task is that it also adds a file watcher to the source files, so if a Cordova build changes the source files (maybe a version update) Aurelia will automatically inject the newer files into our project ... gotta love Aurelia! ....

We still have a problem to solve. The cordova.js file resides in the scripts folder but our <script> tag is trying to load it from the root folder. You may be tempted to change the <script> tag to point to the cordova.js file in the scripts directory. Don't do this! When we build the mobile project in Cordova the cordova.js file will be in the root and not in the scripts folder. The script tag MUST load the cordova.js file from the root folder for our mobile builds to be successful.

OK, don't worry. This is all by design. Remember, these copied files are only used during development and not in production. What we will do to solve this little problem is create a shim file in the root directory that loads the cordova.js file located in the scripts directory. This shim file will also be called cordova.js so our script tag in the index.html file can remain the same between development and production builds.
  1. Add a new file to the project root and save it as 'cordova.js'

  2. Open this file in the editor and add the following code. This injects a new script tag into the document body that loads the cordova.js script in the scripts folder. Remember, this file gets replaced by the real cordova.js file during production builds ... this is only a shim for the development environment.

  3. Open 'client/main.js' in the editor. We need to delay the Aurelia start until after Cordova loads. Cordova adds an event called 'deviceready'. We will add a listener that will start Aurelia.

OK ... It's time to try to test this. When we run the Aurelia project it should load Cordova first, then launch our familiar "Hello World" start page.
  1. Run command 'au run --watch'
  2. Open a browser to localhost:9000 and inspect the page
  3. The Cordova file error should not appear. Instead you should see the Cordova plugins reporting followed by the Aurelia starting message. There are some new errors introduced by the splash screen plugin. We will take care of those next.

  4. Open the Network tab in Dev Tools and refresh the browser.
  5. You will see the Cordova files load as well as some files needed by the Cordova platform.

  6. We now have a fully operational Cordova framework included in out Aurelia desktop development environment! ... life is good ...
Let's get rid of the remaining console errors. These are generated by the Splash Screen plugin. The splash screen is required on mobile devices to display something to the user while the device loads and initializes the app. It is not required by our browser platform so we can simply disable it. If you want a functional splash screen in the browser platform you can opt to supply a logo image and set the configuration parameters. (Note: You will have to delay the Aurelia start function because it replaces the <body> elements and effectively removes the splash screen when it starts) For this project I am going to disable it, but only for the browser platform.

  1. Open the 'config.xml' file found in the project root in your editor.
  2. Add the following node

  3. Run command 'au run --watch'
  4. Inspect the console. All errors should be gone.


 NOTE: Remember to terminate your command session and re-run 'au run --watch' after making any changes to the root of the project. The Aurelia file watcher only watches the interior project files so it may not catch your changes!


Next we will merge our Aurelia project into the Cordova project so that when Cordova builds it will be building our project instead of the sample Cordova project.



No comments:

Post a Comment