Sunday, December 30, 2012

Using Dart for Chrome Packaged Apps (blog post + webcast feat. Kevin Moore and Adam Singer)

Update (9th Jan 2013) - The editor is now able to help you develop chrome apps - check out the news.

You can use Dart to build webapps, running Dart on the server side, or converted to JavaScript in the browser, client site.  But what about “native” apps, that appear to be part of the surrounding OS, and not part of a web browser?  Through a fortunate combination of technologies, you can now build “native-like” apps using Chrome Packaged Apps technology, with the structured Dart language.

Take a quick (~1 min) look at Kevin Moore’s Pop-pop-win game, written in Dart, and converted into a Chrome Packaged App, which you can install from the Chrome Webstore.

Chrome Packaged Apps are Apps that deliver a native experience, but are written as web-apps using web technologies, such as HTML5, CSS and JavaScript, or Dart. They run in a Chrome process that is separate from the web browser, and as such, blend seamlessly into your OS alongside other native apps. In addition, they have greater access to the underlying hardware, such as USB or serial ports, socket level protocols, and the file-system via the chrome.* API libraries. Once you have packaged your app, you can send it to the chrome webstore for other users to download and install, where it is available as a stand-alone application.

Later in this blog post, we will convert the Dart Editor's "Hello World" application into a Chrome Packaged App, but first, let me introduce Dart developer experts +Kevin Moore and +Adam Singer. I interviewed them a couple of days ago about their experiences with Chrome Packaged Apps in Dart. Kevin discusses his experience building pop-pop-win as a chrome packaged app, and Adam talks about his chrome.dart library project, which exposes many of the chrome.* API’s to a Dart application.

Many of the url's and apps referenced in the webcast are listed in the references section at the end of this blog post.

Creating your own Packaged App

In the rest of this blog post, you will see how you can convert the Dart Editor’s “Hello World” app into a Chrome Packaged App, as shown in the image below.

The Dart Editor "hello world" as a Chrome Packaged App
We’ll be using the standard Hello Dart app that appears when you select File > New Application in the Dart Editor.  My project name for this example is hello_world, you can grab the source code from github, or simply create a new Dart project called hello_world.

To turn this into a chrome packaged app, you need to provide two extra files, and some icons for your app.  

The first extra file is an application manifest file, called manifest.json, which provides a description of your app to chrome, including the permissions, icon files and background JavaScript file to run on launch.  The second file is the background JavaScript script file, in my example, called background.js.  This background script file is loaded by Chrome and listens to the onLaunched() event, and navigates to your app’s start page - the normal Dart entry point html file, for example, hello_world.html.  This hello_world.html is the same html file that you would use to launch your app, whether it is a Dart app or a JavaScript app.  The link between these files is shown in the image below.

How the packaged app files link into your Dart app
For a chrome packaged app to run correctly, you need to provide all the files that the app needs to run offline, and this includes the dart.js that is normally downloaded from googlecode.   For the chrome packaged app to work correctly, you need to download the dart.js file and copy it into your project (and update the script reference in the hello_world.html file.

One final step with Dart is to convert the your Dart app to JavaScript using dart2js, but you need to use the flag --disallow-unsafe-eval, which prevents dart2js from creating JavaScript that calls eval() and creating functions dynamically (which is not allowed in a chrome packaged app, per Content Security Policy (CSP) rule).  An example command line, from the /web/ folder, could look like:

 dart2js ./hello_world.dart -ohello_world.dart.js --disallow-unsafe-eval

This outputs the correct JavaScript for use by Chrome in your packaged app.

Installing a Packaged App from a local folder

To install a packaged app that you are developing into Google chrome (in other words, not yet on the webstore), you have to turn on the extensions developer mode.
Navigate to the chrome://chrome/extensions/ url and turn check “Developer Mode” - this lets you install packaged apps directly from your local file system - see the image below.

Chrome extensions developer mode
You can use the Load unpacked extension... option to browse to the folder containing the manifest.json file, and the app will be installed into Chrome from there.  When you are happy with your app, you can Pack extension and upload it to the chrome webstore, like Kevin Morre’s Pop-pop-win. As you edit your app, and regenerate the JavaScript using dart2js, hit the "reload" button against your app's entry in the chrome extensions page to have Chrome reload the app's sourcecode.

Once running as a Chrome packaged app, your Dart app gets access to the chrome.*  API namespace.  Check out Adam Singer's project to build a set of Dart wrappers that makes it easy to access this API in your Dart app.


No comments:

Post a Comment