The best way to develop and run NativeScript projects in an emulator

I develop NativeScript on Windows. As in most new, shiny technology, developing on Windows has it's quirks. In this post, we'll talk about 3 different ways to run your NativeScript project in an emulator, as well as the pros and cons of each method. I'm also going to use the Android platform. The iOS commands are the same, except for swapping iOS for the keyword android in the command.

All methods assume you have an emulator for your platform, with a device profile created. Additionally, at least on Android, it is necessary to start the device emulator you wish to target using the Android Virtual Device Manager, or some other mechanism.

Basic: tns run android --emulator

Run this command every time you want to push the latest version of your code to the emulator.

Pros:

  • You get to see any console output. This means you can debug your application using console.log("foo") statements and see the output.
  • You will stay up to date on your facebook feeds. See Cons below for explanation.

Cons:

  • The console logs are VERY chatty. There are heaps of measurement logging and other things not immediately relevant to the application. The sheer amount of logs, can make it hard to find your output.
  • You'll pay a 2 minute tax, at least, waiting on the emulator to get your changes. Change a single character and use this method again? Then you'll pay the 2 minute tax again. (I'm using an SSD laptop with 16GB of RAM.)
  • Because of the latency between updates, I am painfully reminded of my poor typing skills.
  • If this was the only option to write Native mobile applications, I'd probably decide it wasn't for me and go do something else.

Tip:

At this stage, I can not see a single positive reason to use tns run android --emulator that can't be achieved with one of the below options. In short, you probably don't want to use the workflow tns run android --emulator. As a stretch, perhaps you need to see the Native logs, like all of the measurement logging. Right now I don't need that, so this method is pointless and masochistic.

Interactive: tns livesync android --emulator --watch

This process watches for source code changes and will automatically build and push the latest version of your code to the emulator.

Pros:

  • The time between making a source code change, and seeing the effect of the change in the emulator, is WAY faster than tns run android --emulator. This is somewhat comparable to running a browser based application.
  • I prefer this method when I'm working on layouts, visual changes, or light work inside view-models.
  • Did I mention how fast changes are propagated?
  • If there is an error, you will get a stack trace on your emulator screen.
  • As of NativeScript 1.5, you will see console.log() outputs in your terminal window. YAY!

Cons:

  • You get NO console output. All console.log() statements are /dev/null'd.This is no longer true as of {N} 1.5. Console.log() output is streamed to the terminal, without the chattiness of the above method.

Tip:

If you want more options with how to deal with non-visual logging in NativeScript, write a custom TraceWriter and push the output you want into a frame of your application, or send it over an API or whatever. You can find out more here: tracing-nativescript-applications. Just search for Writing a Custom TraceWriter for an example of your options.

Genymotion: tns debug android --geny "Google Nexus 4 - 5.1.0 - API 22 - 768x1280" --debug-brk

This process watches for source code changes and will automatically build and push the latest version of your code to the emulator and start a debugging session in Google Chrome.

Pros:

  • Changes are propagated quickly, much like tns livesync android --emulator --watch
  • You have introspection, breakpoint and other tools using Google Developer Tools.
  • From my informal testing, the time to complete the initial build and show the app on the screen is less with Genymotion, than it is with the tns livesync android --emulator --watch process.

Cons:

  • This requires a separate account with Genymotion. There is a free personal account and several paid options.
  • No matter what I do, this doesn't work on my platform. It's the albino tiger of debugging. If you can see it working, then you have something special. However, Genymotion never comes out of the cave to perform for me.

Which one should you use?

Once your environment is successfully set up, spend some time to get Genymotion installed. If you can get it working on your system, then you have the Holy Grail of NativeScript debugging. Fast change propagation, interactive debugging, variable inspection and so on. If this does not work for you, then you are probably best served using tns livesync android --emulator --watch. Now that console.log() statements are sent into the terminal, you can debug iteratively, though without the breakpoints and introspection you'd get in a Google Chrome debug session.

Appendix: why doesn't Genymotion work on your platform?

If I knew the answer to that, I wouldn't have been inspired to write this article. I'd just use Genymotion and be happy.

On my system, I can start the Genymotion emulator, connect with a debugging session in Google Chrome and see my application successfully deployed. What does not work is the debugging session. I get the following error in my javascript console:

view plain print about
1Page.getResourceTree failed.
2ReferenceError: process is not defined

While googling for a resolution, I can see others report a similar issue, however no combination of repudiation steps makes this error go away. Thus, the debugging session is not enabled and I get none of the benefits of using Genymotion.

It is a shame, but I make do with the combination of tns run android --emulator and tns livesync android --emulator --watch as needed.

There are no comments for this entry.

Add Comment Subscribe to Comments