Chapter 2. “Hello World” with Dart tools

This chapter covers

  • Discovering the Dart tool set
  • Building apps with the Dart Editor
  • Tools for debugging apps
  • Running apps in the browser
  • Deploying apps to JavaScript

Dart has a rich tool ecosystem that enables you to write, run, and debug Dart code in a variety of environments. Google takes a “batteries included” approach to the Dart tools and fully intends to provide all the tools you’ll require to build complex applications. The Dart tools are currently available for Windows, Mac, and Linux platforms; you can find them on Google’s dartlang.org website.

The Dart tool set starts with the Dart Virtual Machine (Dart VM). The virtual machine exists in two guises. First, it’s on the server as a command-line runtime environment, similar to a Java, Python, or Ruby VM; you’ll use this version to run a simple “Hello World” application. In its second incarnation, it’s embedded in a version of the Chrome web browser called Dartium, where it has access to the browser document object model (DOM). You’ll see Dartium when you use the Dart Editor to edit and run the same “Hello World” application in the browser, but this time hosting the Dart script in an HTML file.

You’ll also use the Dart Editor, which is capable of building applications that run both in the browser and on the server, to enable debugging and refactoring of the “Hello World” app. Here, you’ll use the dart2js tool, which compiles the various Dart source files and libraries into a single JavaScript application.

You’ll use the dartdoc tool to generate formatted HTML API documentation from your code’s comments. This is the same tool that creates Google’s own Dart API documentation website, and you’ll use it to produce documentation for your “Hello World” app.

When you choose Dart as a platform for writing web apps, you get more than language features: you get to use the tools developed by Google for Google. Download the Dart Editor, which bundles all the tools you need, including the Dart software development kit (SDK) and the Dartium browser, and we’ll start exploring.

2.1. The command-line Dart VM

There are versions of the Dart VM for Windows, Mac, and Linux platforms. This allows you to write Dart code that runs without a web browser and accesses the capabilities of the machine, including the filesystem and socket-level network I/O. The VM uses an asynchronous, event-loop model, similar to Node.js (which is a server-side VM based on the Chrome JavaScript VM). The Dart event-loop model runs your code to completion and then passes control to the event loop, which notifies your code when something interesting happens, such as a file becoming open or data being retrieved from a TCP socket.

Let’s start with a basic Dart script—the simplest “Hello World” script, in fact, that you can achieve in a single line that outputs the string "Hello World" to the console.

Listing 2.1. HelloWorld.dart

This single-line function, called main(), is the entry point for all Dart applications. You can also write it using the more traditional function syntax, with the function body surrounded by curly braces:

main() {
  print("Hello World");
}

To run this code, save it in a text file, give it a .dart file extension, and pass it as a parameter to the Dart binary found in the downloaded Dart-SDK’s bin folder. On Windows, this is dart.exe. The output is shown in figure 2.1.

Figure 2.1. The Dart VM as a command-line tool

The Dart VM can also be embedded in other applications, but this topic is outside the scope of this book. Possible applications include providing a Dart scripting environment in a text editor, similar to the way the Python runtime is embedded in popular editors such as Sublime Text.

Although you can run Dart scripts from the command line—and you’ll run server-side Dart applications in a production environment from the command line—it isn’t ideal as a development tool. Fortunately, the Dart Editor, which we’ll look at next, lets you run command-line Dart VM executables in the Dart Editor, along with running Dart in the browser-hosted Dart VM.

We’ll look in much more depth at server-side programming, including the event loop and accessing server-side resources such as files, in part 4 of this book, where you’ll build a web server and use HMTL5 web sockets to communicate with Dart running in the browser.

 

Remember

  • The Dart VM is available as a server-side binary that runs from the command line.
  • The server-side Dart VM has full access to server-side APIs, such as the filesystem and network sockets.

 

2.2. “Hello World” with the Dart Editor

The Dart Editor has a growing number of essential tools to help you develop and debug Dart code. Some of these are code navigation, code autocomplete, refactoring, and information about errors and warnings. Although Dart—like many dynamic, interpreted languages—can be written in just about any text editor, the Dart development team has put significant effort into providing a fully featured developer experience that is often missing from other JavaScript alternatives.

You’ll start by using the Dart Editor to run the same HelloWorld.dart script in the server-side Dart VM, this time launched from the Dart Editor. Then you’ll modify the script to enable it to be hosted in an HTML page and run in the browser-based Dart VM, which is built into the Dartium web browser that comes bundled with the Dart Editor.

Figure 2.2 shows the Dart Editor that you’ll be working with throughout the rest of the book.

Figure 2.2. The Dart Editor is a lightweight version of the Eclipse tool.

2.2.1. Exploring the Dart Editor tools

The Dart Editor provides the standard range of developer tools such as method and property autocomplete, refactoring, code navigation, and syntax checking and debugging. When you edit your app with the Dart Editor, your code, and the code of all the external libraries that make up your application, is validated for errors and warnings. Internally, the Dart Editor uses the dart_analyzer tool to provide static analysis of the Dart code. This tool can also be used on the command line—for example, to integrate it into a continuous-build system such as Hudson, CruiseControl, or Bamboo.

 

Note

At the time of writing, the command-line version of the dart_analyzer tool is available only on Mac and Linux platforms. The Windows version is still under development.

 

You can use the output from dart_analyzer in the Dart Editor to highlight lines of code that that may contain errors or could be considered warnings, as shown in figure 2.3.

Figure 2.3. Errors and warnings are shown in the Dart Editor.

This error-checking also allows the Dart Editor to provide some quick-fix capabilities. For example, the Editor gives you the option to create a new prnt(String string) function stub based on its knowledge of the missing prnt() method. The warning shown in figure 2.3 is telling you that a + method is missing on the String object. This may be valid code, as you’ll see when we look at handling noSuchMethod() in chapter 7, so it’s flagged as a warning rather than an error. You can execute code that contains warnings; you can’t execute code that contains errors.

When you run the “Hello World” script, its output is redirected to the Dart Editor’s own console instead of running in a separate console window. The Dart Editor is using the same Dart VM binary that you used in the previous section when you ran the “Hello World” script from the command line. Figure 2.4 shows the output in the Editor’s console window.

Figure 2.4. The Dart VM produces output in the Editor console.

The Dart Editor contains a number of tools to help you navigate around code: your own code and any external libraries you’re using, whether brought in from the Dart SDK or open source libraries.

Code Navigation and the Standard Libraries

The Dart project is open source. That philosophy is baked into the language, and as such, all the standard library code is open source, too. Thus, using the Editor’s code-navigation features, if you want to see what the dart:html ButtonElement class looks like or examine the dart:core List code structure and comments, they’re right there at your fingertips in plain text.

You can navigate directly from your code to the declaration site by using the Open Declaration (F3) command. This command works for both your own code and any other libraries you import. It’s useful, for example, to be able to navigate a hierarchy of method calls throughout several libraries to discover the underlying reason for a particular bug or way of working—especially when you’re developing in a team and someone else has implemented an underlying library or you’re using third-party libraries from the web.

The Dart Editor also has useful Outline and Callers views. The Outline view lets you visualize the outline of your source file, showing top-level functions, classes, and class members. The Callers view, which you activate on a specific function or method, shows which location in your code calls that function. This is similar to Find References in Java and C# tools. Figure 2.5 shows an example.

Figure 2.5. The Dart Editor Callers and Outline views

Code Suggest and Autocomplete

Code autocomplete, although not always needed if you know the source and libraries well enough, is incredibly useful when you’re learning a new library and its features. It lets you see the available methods immediately, in the code, under the cursor. Is there a Sort method on the List class? Is there a way to get a list of char codes from a String? Code autocomplete will tell you this without your needing to leave the Editor—in fact, without leaving the text Editor pane.

This feature is useful when you’re working with someone else’s code, whether it was written by someone else on your team or taken from other projects that you’re using. It could be said that you should not need autocomplete if you knew all the methods and their parameters by heart, but the reality of today’s open source frameworks is that they change rapidly, and having method and parameter information directly in your code can only help.

Code navigation, autocomplete, and error information are common tools that many developers have used elsewhere, and they’re unsurprising in their use. They’re worth noting because few JavaScript editors have these features. One of Dart’s design goals is to make developers’ lives better when developing web applications, and these three tools help to achieve this.

2.2.2. The relationship between Dart and HTML files

Dart is designed to run in the web browser, either as native Dart or converted to JavaScript. To enable this conversion to JavaScript, your application needs to exist separately from the HTML file that defines the host web page. Fortunately, the Dart Editor is also designed to work this way: when you create a new project in the Dart Editor, you have the option of creating a boilerplate HTML file that contains a script tag to run your Dart application.

Listing 2.2 shows the bare-minimum HTML that you need to enable your Dart application to run as either a Dart or a converted JavaScript application. It contains a script tag linking to your existing HelloWorld.dart script. It also contains another JavaScript script called dart.js, which detects whether the host browser contains the Dart VM. If the host browser isn’t Dart enabled, the script modifies any application/ dart scripts to application/javascript and appends a .js suffix to any src properties in those script tags: for example, it changes HelloWorld.dart to HelloWorld.dart.js. The following JavaScript version of your Dart app, as you’ll see shortly, is created by the dart2js tool.

Listing 2.2. HTML file that can run your Dart app in both Dart and JavaScript

The code built into the linked dart.js, which is included in the HTML, contains a snippet of JavaScript that checks to see whether the function navigator.webkitStartDart exists in the browser. You can also use this check in your code to determine whether you’re running in a Dart-enabled browser.

Figure 2.6 shows the relationship between the host HTML file and your “Hello World” Dart script.

Figure 2.6. HTML links to external Dart files

2.2.3. Running “Hello World” with Dartium

From the Dart Editor, you can run this app the same that you did with the Dart VM version. The Dart Editor detects that there is an associated HTML file and loads the app into the Dartium web browser, served from its own built-in server. This built-in server lists all the Dart applications that are currently available in the Editor, as shown in figure 2.7.

Figure 2.7. Viewing the Dart Editor’s web server from Dartium

“Hello World” uses the print() function to output a message. When running in a web browser, print() outputs to the browser’s debug console, similar to the JavaScript console.log() function. The Dartium web browser can communicate with the Dart Editor, and any text that appears in the Dartium debug console is sent back to the Dart Editor’s console. Dartium also knows about breakpoints in the Dart Editor, and code will pause execution in the Dart Editor when a specific breakpoint is reached. We’ll look at this debugging feature a little later in the chapter.

2.2.4. Using dart2js to convert to JavaScript

When your application user doesn’t use a browser that runs Dart natively, they must use the JavaScript version of your app. Fortunately, you can convert Dart code to JavaScript using the dart2js tool (more on that later), which outputs a .js (JavaScript) file that contains a compiled version of the .dart app. The dart2js tool actively removes redundant code, so you can import as many external Dart libraries as you wish, safe in the knowledge that only the code that’s used in your app ends up as JavaScript. You access the dart2js tool from the Editor by selecting Tools > Generate JavaScript from the Editor’s menu.

The complete output of your “Hello World” application contains the readable JavaScript shown in the following listing. It includes the code to start a Dart isolate (the execution unit in Dart) and the print() functionality from the core Dart libraries. The dart2js tool also outputs a sourcemap file, which modern browsers can use to show the original Dart file. Thus although you can view the output JavaScript, you don’t need to.

Listing 2.3. HelloWorld.dart.js: output of dart2js

Now that you have your application code available as both Dart and JavaScript code (from a single Dart source), it’s possible to let the browser switch between the Dart implementation of the app and the JavaScript version. If the browser understands Dart, it will load the .dart code. If not, it will get the .js version of the code.

 

Note

Unlike Google’s Java-based Google Web Toolkit (GWT) product, which outputs different JavaScript files for each targeted browser, dart2js outputs a single JavaScript source. Dart is designed to convert to a single JavaScript output for running in modern web browsers.

 

2.2.5. Generating documentation with dartdoc

Also in the Editor’s’ toolset is the dartdoc tool, which you can use to generate API documentation. If you add a doc comment to your main() function, as shown in the following snippet, you can generate the appropriate API doc:

The API documentation that’s output is the same as that used by the Dart API docs hosted at http://api.dartlang.org. The dartdoc for the “Hello World” app is shown in figure 2.8.

Figure 2.8. Generated dartdoc for your “Hello World” application

2.2.6. Debugging Dart with breakpoints

The Dartium browser and the Dart Editor work in conjunction to enable breakpoints and step-by-step debugging. When you set a breakpoint in the code and run your app with Dartium, two-way communication between the Dart Editor and Dartium allows the Dart Editor to break when your code reaches the breakpoint. In this respect, you get functionality similar to what you might expect from Java or C# application development. You can watch variables, browse the stack, and step over and into method and function calls, all from the Dart Editor.

Figure 2.9 shows this behavior in action, with the source code on the left and the debugger with the call stack and local variables running on the right.

Figure 2.9. Setting breakpoints and debugging in the Dart Editor

 

Remember

  • The Dart Editor comes bundled with the Dart SDK and the Dartium browser.
  • Many code navigation and editing tools are available in the Editor, including code refactoring, the Callers view, and the Outline view.
  • The dart_analyzer tool is used for static analysis of the code. It produces errors and warnings that appear in the Dart Editor.
  • You can create an HTML-formatted API document from your code comments using the dartdoc tool.
  • The Dart Editor and Dartium communicate with each other to provide an integrated, round-trip debugging solution.

 

Live debugging of web apps is a powerful tool. Having the ability to set breakpoints directly from either the Dart Editor (in which you have a quick edit, save, and refresh cycle) is a powerful aid to getting your app working perfectly.

You’ve seen how to edit Dart using the Dart Editor tools and run Dart in the Dart Editor. It’s time to look at using Dart to drive a user interface.

2.3. Importing libraries to update the browser UI

In this section, we look more at how Dart communicates with the browser DOM using the dart:html library. Using the Dart Editor and Dartium to provide quick updates of your code, you’ll modify your HTML file to contain a single <div> element with a DOM ID of "status". You’ll reference this status <div> in your “Hello World” script, updating the content of the script with a "Hello World" string. The following listing shows the new status <div> you’re adding.

Listing 2.4. HelloWorld.html with status <div>

Now that you have an element in your HTML page, you can modify your Dart script to update it. You’ll replace the print statement with one that gets the <div> element from the page. In order to do this, you need to use one of the built-in libraries, called dart:html. The dart:html library is designed to provide all the HTML APIs that you expect from the browser DOM, but in a consistent manner, with Dart-style API access; you’ll see much more of this library throughout the book. If you’re used to using jQuery with JavaScript, then the dart:html library should feel familiar.

2.3.1. Importing Dart libraries

To import a library, you use the import statement. The import statement comes in three variations, which we’ll look at in more detail in chapter 5. The first is used to import core libraries, such as dart:html. In this case, you use the dart: prefix, in this form:

import "dart:html";

Because this library is built into the Dart SDK, the tools know automatically where to find it.

The second flavor of import is used to import third-party dependencies. It uses the package: prefix:

Libraries imported using the package: prefix are resolved using pub, Dart’s package-manager tool, which is available for use on the command line or in the Dart Editor.

Pub can pull dependencies from the internet using code repositories such as GitHub or Dart’s own pub.dartlang.org repository. In this form, it serves a purpose similar to that of Java’s Maven, .NET’s NuGet, and node.js’s npm tool. The most important commands are as follows:

pub install
pub update

The first command installs the dependencies required, and the second updates them. Pub is a new tool and will likely evolve to provide a number of features, such as setting up boilerplate websites and frameworks.

The final flavor of the import statement imports your own local or other local libraries by file path, for example:

import "./myLibraries/helloLibrary.dart";

This form uses an implicit URI to access Dart libraries, which should be accessible by the Dart tools. When you convert Dart to JavaScript, all these imported libraries are pulled together into a single JavaScript file, containing only the code that is used.

2.3.2. Accessing DOM elements with dart:html

Figure 2.10 adds import "dart:html"; into your Dart code and shows the modified main() function, which updates the status <div> with the text "Hello World". The dart:html library provides the query() function shown.

Figure 2.10. Updating the status of a <div> in the browser

The query() function is similar to jQuery’s $() function, which queries the browser DOM by using CSS selectors.

 

CSS selectors

CSS selectors are patterns you can use to pick items out of the browser DOM, and the two most common are #id and .class. There are plenty of tutorials available on the web, but the following is provided as a reminder.

Given the following two lines of HTML

<div id="firstLine" class="myTextBlock">This is div number 1</div>
<div id="secondLine" class="myTextBlock">This is div number 2</div>

you can select both lines by using the CSS selector .myTextBlock (because they both share the same class), but you select the lines individually by using their ID values #firstLine and #secondLine. IDs should be unique, but multiple elements can share a class.

 

2.3.3. Dynamically adding new elements to the page

You’ve seen how you can modify elements that already exist in the HTML page that’s hosting the Dart app, but a single-page application is responsible for building its own user interface from code. This means you need to be able to dynamically create elements. Let’s modify the “Hello World” app once again: this time, add a button that, when clicked, adds a new <div> containing the "Hello World" string. The output will look like figure 2.11.

Figure 2.11. Dynamically adding elements

All browser elements inherit from a base Element object. You have a number of ways to create elements dynamically, by using a tag name, an HTML string, or, for common elements such as Buttons, a specific ButtonElement class. We’ll look again at creating elements in the next chapter and in much more detail in part 3 of the book, when we deal with building client-side web apps.

The next listing shows the modified “Hello World” app, which builds up the user interface.

Listing 2.5. HelloWorld.dart: creating elements dynamically

In this snippet, you created some browser elements dynamically and hooked up your button to an event handler. This event-handler function is an example of an anonymous function, which we’ll look at in more detail in chapter 4.

 

Remember

  • Dart uses the dart:html library to provide access to browser DOM APIs and elements.
  • Your app can create elements dynamically and add them to the browser DOM.
  • You can use the pub package-management tool to import external libraries.
  • You can import libraries directly on the filesystem.

 

2.4. Summary

In this chapter, we’ve examined the tools that are available to the Dart developer. Many languages have the same aims as Dart, but few of them provide the rich tool set that goes along with the language:

  • The Dart Editor, Dartium, and the Dart VM provide tools to help you write, run, and debug Dart code.
  • dart2js converts Dart code to JavaScript, which targets modern web browsers.
  • Dart has built-in libraries that let you interact with the web browser’s DOM in a friendly manner.

Using the Dart Editor and Dartium together should aid you as you learn and experiment with the Dart language and core libraries. The quick develop-and-run cycle that you get by being able to run Dart code directly in the Dartium web browser, without needing a compile step, gives you a great productivity boost, because it becomes simple to try parts of the language and see your results immediately.

In the next chapter, you’ll start to build a real client-side Dart application. We’ll take a high-level look at some of the Dart language concepts you’ll see again in more depth throughout the rest of the book, including optional typing and classes. You’ll also see how you can use Dart’s unit-test framework to begin testing your app.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.76.138