I've been really liking Visual Studio Code lately, so much so that it is now my primary editor. It is still definitely a pre-1.0 release, but it performs really well and I just dig its coding style. I had to step away from Brackets a few weeks ago due to a bug (details) that impacts AngularJS/Ionic apps. Since that's what I work with most of the time, Brackets simply became too frustrating to use. One of the cool features of Visual Studio Code is the ability to define Tasks for a project. You can support one or more different tasks for a project simply by adding a tasks.json file to the .settings subdirectory. VSC will even create a good default with lots of examples for you to modify. Even nicer, since VSC supports intellisense for JSON schemas, you get code hints while building the file. This morning I thought I'd write up a quick example of adding support for emulating Cordova app.

I began by following the suggestion in the Tasks doc, I typed Shift+Command+P and then Configure Task Runner, which is slightly different than what the docs say. This created the JSON file with an initial default task that I immediately commented out.

While you can do a lot with the Cordova CLI, I really spend most of my time doing cordova emulate. VSC supports multiple tasks, but you can specify just one and doing so let's you treat it as a build command. That means you can simply type Shift+Command+B to execute it. Here's my first draft:

{
	"version": "0.0.1",
	"command": "cordova",
	"isShellCommand": true,
	"showOutput": "never",
	"args":["emulate"]
}

Notice I'm not passing a platform. If you have multiple platforms defined than all will be sent to the emulator. This will be a problem that I'll cover in a second.

Also note the showOutput command. You can specify three different values here:

  • never - means what you think it does
  • silent - will show output if you don't configure problem matchers - you can see an explanation of that here: Defining a Problem Matcher
  • always - means what you think it does

However, in my testing, showOutput:never didn't actually work. I just made the output window a bit smaller and later today I'll file a bug report on it. On a larger screen (i.e. not this laptop) I wouldn't even care. Here it is in action.

shot1

So what if you want to specify the platform to emulate? You can define multiple tasks like so:

{
	"version": "0.0.1",
	"command": "cordova",
	"isShellCommand": true,
	"args":["emulate"
	],
	"tasks": [
		{
			"taskName": "ios",
			// Make this the default build command.
			"isBuildCommand": true,
			// Show the output window only if unrecognized errors occur.
			"showOutput": "silent"
		},
				{
			"taskName": "android",
			// Make this the default build command.
			"isBuildCommand": false,
			// Show the output window only if unrecognized errors occur.
			"showOutput": "silent"
		}

	]
}

In this case, I've defined an ios and android task to pass to the emulate command. Note that I've still set ios to be the build command so I can use it as a default. One thing I don't like about this is that I can't provide a 'label' for the tasks. So when I do Shift+Command+P, Run Tasks, I see it like so:

shot2

That's not the end of the world, but I'd like to have a label so I could see "Emulate iOS" and "Emulate Android (please wait 2-3 hours for the emulator to start)".

This works, but has a problem. When emulating Android, the CLI hangs while the emulator is running. If I run Android via VSC, it works (after the emulator finally loads up), but VSC will not let me run another tasks until this one ends. I have to kill the emulator to continue.

Ok, so I worked on this a bit more. I don't actually emulate Android as it is way too slow, what I do normally is use Genymotion and use the run command instead. Yes, this is still emulating, but the command line call is tweaked. I just tried this and it worked!

{
	"version": "0.0.1",
	"command": "cordova",
	"isShellCommand": true,
	"args":[
	],
	"tasks": [
		{
			"taskName": "ios",
			// Make this the default build command.
			"isBuildCommand": true,
			// Show the output window only if unrecognized errors occur.
			"showOutput": "silent",
			"args": [
				"emulate"
			]
		},
				{
			"taskName": "android",
			// Make this the default build command.
			"isBuildCommand": false,
			// Show the output window only if unrecognized errors occur.
			"showOutput": "silent",
			"args": [
				"run"
			]
		}

	]
}

So I can now Shift+Command+B to send to iOS as my default, or do Shift+Command+P, Run Task, to select android if I need to.

shot3

Hope this helps, and I'm going to keep an eye out for other ways to help VSC work with Cordova.