Chromium Code Reviews| Index: src/site/codelabs/deploy/index.markdown |
| diff --git a/src/site/codelabs/deploy/index.markdown b/src/site/codelabs/deploy/index.markdown |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..facbe2ed263c8fd0a3ceb732b7dd8bb0af4e6efe |
| --- /dev/null |
| +++ b/src/site/codelabs/deploy/index.markdown |
| @@ -0,0 +1,1208 @@ |
| +--- |
| +layout: tutorial |
| +title: "Weigh Anchor: Deploy a Server and App" |
| +description: "Deploy a Dart server and serve a Dart app." |
| +has-permalinks: true |
| +tutorial: |
| + id: buildanddeploy |
| +js: |
| +- url: /js/os-switcher.js |
| + defer: true |
| +- url: /js/editor-downloads-analytics.js |
| + defer: true |
| +- url: /js/editor-version.js |
| + defer: true |
| +header: |
| + css: ["/codelabs/darrrt/darrrt.css"] |
| +--- |
| + |
| +# {{ page.title }} |
| + |
| +<div style="font-size:164px;font-weight:bold;color:#DCDCDC"> |
| +DRAFT |
| +</div> |
| + |
| +Now, we switch from client-side programming to server-side. |
|
sethladd
2014/01/24 23:03:03
This sentence is very context-heavy. That is, what
mem
2014/01/24 23:55:05
Done.
|
| + |
| +<div class="trydart-note" markdown="1"> |
| +<strong>Note:</strong> |
| +This code lab is for those who want to learn |
| +how to write a DIY server for deploying a web app. |
| +If you are not interested in server-side programming, |
| +this code lab is probably not for you. |
| +Perhaps you'd prefer the |
| +[Avast, Ye Pirates](/codelabs/darrrt/) code lab |
| +for building a web app. |
| +</div> |
| + |
| +To put your app on the internet, you need to deploy it. |
| +For that, you need an app, a server, and a host. |
|
sethladd
2014/01/24 23:03:03
server is overloaded... I need a physical (or virt
mem
2014/01/24 23:55:05
Done.
|
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| + |
| + |
| +</div> |
| + |
| +You can use any server to serve your Dart app, |
|
sethladd
2014/01/24 23:03:03
global: clarify server to web server
mem
2014/01/24 23:55:05
Done.
|
| +but one of the interesting things about Dart is that it |
| +runs on both the client and the server, so you |
|
sethladd
2014/01/24 23:03:03
this seems like a long sentence
mem
2014/01/24 23:55:05
Done.
|
| +can use Dart for both ends of your project. |
| +One benefit of doing so is that the client and server |
| +can share code. |
| +Dart also runs on Windows, Linux, or Mac systems. |
|
sethladd
2014/01/24 23:03:03
not sure we need the word 'also' here.
Should we
mem
2014/01/24 23:55:05
Done.
|
| + |
| +* **Server**—In this code lab, you learn how to build a server in Dart |
|
sethladd
2014/01/24 23:03:03
clarify to web server
mem
2014/01/24 23:55:05
Done.
|
| +that can serve static files (those that have no dynamic content). |
| +You use this server to respond to HTTP requests for the app's pages. |
| + |
| +* **Host**—In addition to a server, you need a host for your app. |
| +Many public hosting services are available. |
| +We chose the Heroku hosting service for this project |
| +because it has a free tier and is easy to use. |
| + |
| +* **App**—As for the app, you will be deploying the Pirate Badge app from the |
| +[Avast, Ye Pirates](/codelabs/darrrt/) code lab. |
| + |
| +* **Fun debugging on mobile devices**—In addition, |
| +you learn how to use DevTools to inspect and debug your app on a mobile device. |
| + |
| +<hr> |
| + |
| +<div markdown="1"> |
| + |
| +## Table of Contents |
| + |
| +* [Step 0: Set up](#step-zero) |
| +* [Step 1: Run the app in Dartium](#step-one) |
|
sethladd
2014/01/24 23:03:03
global: qualify app as client app?
mem
2014/01/24 23:55:05
Done.
|
| +* [Step 2: Build the app and run as JavaScript](#step-two) |
| +* [Step 3: Walk through the static server's code](#step-three) |
| +* [Step 4: Inspect your app on a mobile device](#step-four) |
| +* [Step 5: Deploy to Heroku](#step-five) |
| +* [Step 6: Run the app on the web and on a mobile device](#step-six) |
| +* [Resources](#resources) |
| +* [What next?](#what-next) |
| + |
| +</div> |
| + |
| +<hr> |
| + |
| +##Step 0: Set up {#step-zero} |
| + |
| +In this step, you download Dart and get the code for the app that you will be deploying. |
| +This code lab uses Dart Editor. |
| + |
| +### <i class="fa fa-anchor"> </i> Get Dart. |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| +If you haven't already done so, |
| +get the Dart download. |
| +Unzip the ZIP file, which creates a directory called `dart`. |
| + |
| +<!--style here is a hack to remove the arrow, which was only partially showing. --> |
| +<div style="padding-left: 10px"> |
| + {% include downloads/_dart-editor.html buttonclass="btn btn-primary btn-lg" %} |
| +</div> |
| + |
| +<p class="os-choices" markdown="1"> |
| + The Dart tools |
| + work in recent versions of |
| + {% include os-choices.html %} |
| +</p> |
| +</div> |
| + |
| +### <i class="fa fa-anchor"> </i> Start Dart Editor. |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| +Go to the `dart` directory and double-click **DartEditor**. |
| + |
| +**Got questions? Having trouble?** Go to the |
| +[Troubleshooting Dart Editor](/tools/editor/troubleshoot.html) page. |
| + |
| +</div> |
| + |
| +### <i class="fa fa-anchor"> </i> Get the code. |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| +<a href="https://github.com/marycampione/deploy-codelab/archive/master.zip">Download</a> |
| +the code for the app that you will be deploying. |
| +Unzip the ZIP file, |
| +which creates a directory called `deploy-codelab`. |
| +</div> |
| + |
| +### <i class="fa fa-anchor"> </i> Open deploy-codelab. |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| +In Dart Editor, |
| +use **File > Open Existing Folder...** |
| +to open the `deploy-codelab` directory. |
| +</div> |
| + |
| +<div class="row"> <div class="col-md-7" markdown="1"> |
| + |
| + |
| + |
| +<div class="trydart-note" markdown="1"> |
| +<strong>Note:</strong> |
| +If you see <span style="color:red">red X's</span> at the left of the |
| +filenames, |
| +the packages are not properly installed. |
| +Right click `pubspec.yaml` and select **Pub Get**. |
| +</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* The `packages` directory, |
| + as well as the `pubspec.yaml` and `pubspec.lock` files, |
| + are related to package dependencies. |
|
sethladd
2014/01/24 23:03:03
what are package dependencies?
suggestion: The pa
mem
2014/01/24 23:55:05
Done.
|
| + This project has all the dependencies set up for you. |
| + Dart Editor automatically installs the necessary packages. |
| + |
| +* The `web` directory contains the Pirate Badge app to deploy. |
| + |
| +* The `bin` directory contains the code for a static file server. |
|
sethladd
2014/01/24 23:03:03
The bin directory contains Dart scripts that run f
mem
2014/01/24 23:55:05
Done.
|
| + You can use the server for testing and debugging your app |
|
sethladd
2014/01/24 23:03:03
The first-order function of the server is to serve
mem
2014/01/24 23:55:05
Done.
|
| + on your local machine and on mobile devices. |
| + Also you can use it to deploy to Heroku, |
| + which requires that you provide a server with your project. |
| + |
| + |
| + {% comment %} non-breaking space required for bootstrap/markdown bogosity {% endcomment %} |
| + |
| +</div> </div> |
| + |
| +<hr> |
| + |
| +##Step 1: Run the app in Dartium {#step-one} |
| + |
| +Open the code for the Pirate Badge web app and run it locally. |
| + |
| +### <i class="fa fa-anchor"> </i> Expand the `web` directory. |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| +In Dart Editor, expand the `web` directory |
| +by clicking the little arrow |
| + to the left of its name. |
| +The directory contains four files: |
| + |
| + |
| + |
| +</div> |
| + |
| +### <i class="fa fa-anchor"> </i> Look at `piratebadge.html`. |
| + |
| +<div class="row"> <div class="col-md-7"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +Double-click `piratebadge.html` to open it. |
| + |
| +{% prettify html %} |
| +... |
| +<head> |
| + <meta charset="utf-8"> |
| + <title>Pirate badge</title> |
| + [[highlight]]<meta name="viewport"[[/highlight]] |
| + [[highlight]]content="width=device-width, initial-scale=1.0">[[/highlight]] |
| + <link rel="stylesheet" href="piratebadge.css"> |
| +</head> |
| +<body> |
| + ... |
|
sethladd
2014/01/24 23:03:03
I really wanted to see a reference to the script t
mem
2014/01/24 23:55:05
Done.
|
| + [[highlight]]<script src="packages/browser/dart.js"></script>[[/highlight]] |
| + ... |
| +</body> |
| +... |
| +{% endprettify %} |
| + |
| +</div> |
| + |
| +<div class="trydart-filename">piratedbadge.dart</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* The <code><meta></code> tag sets attributes to |
| + make the app scale correctly on mobile devices. |
| + |
| +* `dart.js` is a script that determines if the browser supports Dart, |
| + and if it does, runs the app natively. |
| + If it does not, the script loads the JavaScript version of the app. |
| + |
| +* `dart.js` is part of the `browser` pub package. |
| + |
| +</div></div> |
| + |
| +### <i class="fa fa-anchor"> </i> Run the app. |
| + |
| + |
| +<div class="row"> <div class="col-md-7"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +Right-click `piratebadge.html` |
| +and choose **Run in Dartium** from the menu. |
| + |
| + |
| + |
| +</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* Dart Editor launches *Dartium*—a special build of Chromium |
| + that has the Dart Virtual Machine built in—and loads the app. |
| + |
| +* At this time, Dartium is the only browser that has the Dart VM built in. |
| + To run a Dart app in other browsers you need to convert it to JavaScript, |
| + which you do in the next step. |
| + |
| +</div></div> |
| + |
| +<div class="row"> <div class="col-md-7"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +</div> |
| + |
| +<iframe class="running-app-frame" |
| + style="height:220px;width:550px;margin-top:20px;margin-bottom:20px" |
| + src="/codelabs/darrrt/examples/6-piratebadge/piratebadge.html"> |
| +</iframe> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* The Pirage Badge app should appear. |
| + |
| +* Try out the app running to the left. |
| + Click the button or type in the text field to generate a pirate name. |
| + |
| + {% comment %} non-breaking space required for bootstrap/markdown bogosity {% endcomment %} |
| + |
| +</div></div> |
| + |
| +<hr> |
| + |
| +##Step 2: Build the app and run as JavaScript {#step-two} |
| + |
| +In this step, you use `pub build` to |
| +generate the assets for the app |
| +and put them into a new directory named `build`. |
| +In addition to other tasks, |
| +this process generates minified JavaScript that |
| +works in any modern browser. |
| + |
| +### <i class="fa fa-anchor"> </i> Check out pubspec.yaml |
| + |
| +<div class="row"> <div class="col-md-7"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +Double-click the `pubspec.yaml` file to open it. |
| +Click the **Source** tab at the bottom of the editing pane. |
| + |
| +{% prettify dart %} |
|
sethladd
2014/01/24 23:03:03
Why is this important to building the app?
mem
2014/01/24 23:55:05
Done.
|
| +name: deploy_codelab |
| +description: A sample deployment |
| +dependencies: |
| + [[highlight]]browser: any[[/highlight]] |
| + [[highlight]]http_server: any[[/highlight]] |
| + [[highlight]]path: any[[/highlight]] |
| +{% endprettify %} |
| + |
| +</div> |
| + |
| +<div class="trydart-filename">pubspec.yaml</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* A `pubspec.yaml` file in a directory identifies the directory |
| + and its contents as a package. |
| + |
| +* `pubspec.yaml` provides meta-data for the application, |
| + such as its name. |
| + |
| +* The `pubspec.yaml` file also lists the packages on which the app depends. |
| + The three packages needed by this app are all hosted on |
| + [pub.dartlang.org](https://pub.dartlang.org/). |
| + |
| +* `any` selects the latest version of the package that matches your SDK. |
| + |
| +</div></div> |
| + |
| +### <i class="fa fa-anchor"> </i> Look at the packages directory |
| + |
| +<div class="row"> <div class="col-md-7"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +In Dart Editor, expand the top-level `packages` directory. |
|
sethladd
2014/01/24 23:03:03
why is this important to building the app? that is
mem
2014/01/24 23:55:05
Done.
|
| + |
| + |
| + |
| +</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* The `packages` directory contains the code for all of the dependencies |
| + listed in the `pubspec.yaml` file. |
| + These are installed automatically by Dart Editor. |
| + |
| +* The `browser` package contains the `dart.js` script |
| + that checks for native Dart support. |
| + |
| +* The `http_server` package implements high-level HTTP server |
| + functionality, making it easier to write HTTP server code. |
| + |
| +* The `path` package provides common path manipulation operations, |
| + such as joining, splitting, and normalizing. |
| + |
| +* The `mime` package is included because `http_server` depends on it. |
| + |
| +* You're likely to see multiple `packages` directories. One is installed |
| + for every subdirectory that needs it. |
| + |
| +</div></div> |
| + |
| +### <i class="fa fa-anchor"> </i> Run pub build |
| + |
| +<div class="row"> <div class="col-md-7"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +With `pubspec.yaml` still selected, |
| +select **Tools > Pub Build**. |
| +The output looks something like this: |
| + |
| +{% prettify bash %} |
| +--- Jan 16, 2014 4:14:36 PM Running pub build ... --- |
| +Building deploy_codelab..... |
| +[Info from Dart2JS]: |
| +Took 0:00:06.811770 to compile deploy_codelab|web/piratebadge.dart. |
| +Built 10 files! |
| +{% endprettify %} |
| + |
| +</div> |
| + |
| +<div class="trydart-filename">terminal</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* The `pub build` command creates a `build` directory that contains |
| + everything your app needs to be deployed, including a minified |
| + JavaScript file and the required packages. |
| + |
| +</div></div> |
| + |
| +### <i class="fa fa-anchor"> </i> Look at the `build` directory |
| + |
| +<div class="row"> <div class="col-md-7"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +The `pub build` command creates a `build` directory |
| +under `deploy-codelab`. |
| + |
| + |
| +</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* The `piratebadge.dart.js` file is a JavaScript file that has been minified. |
| + When deployed, this file runs in the browser. |
| + |
| +* The `packages` directory contains the package dependencies. |
| + |
| +* Note that the `build` directory contains no `piratebadge.dart` file. |
| + It is not needed to deploy the app to JavaScript. |
| + |
| +</div></div> |
| + |
| + |
| +### <i class="fa fa-anchor"> </i> Run the app as JavaScript |
| + |
| +<div class="row"> <div class="col-md-7"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +Open the app. |
| +Select **File > Open File...** |
| +in a browser such a Firefix or Safari |
| +and select the |
| +`deploy-codelab/build/piratebadge.html` file. |
| + |
| +</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* The app is running on the local machine using the `file` protocol. |
| + To share your app with others, you need to deploy the app to a hosting service, |
| + such as Heroku. |
| + |
| +</div></div> |
| + |
| +<hr> |
| + |
| +##Step 3: Walk through the static server's code {#step-three} |
| + |
| +A static file server is a stand-alone application that listens |
|
sethladd
2014/01/24 23:03:03
can you clarify that you can write dynamic HTTP se
mem
2014/01/24 23:55:05
Done.
|
| +for and responds to HTTP requests with the contents of pages that have no |
| +dynamic content. |
| +Typically, static file servers get requests for `index.html` and other |
| +HTML files plus the assets, such as images, required by that file. |
| + |
| +You need to provide a static server for this project |
| +because Heroku requires one for deployment. |
|
sethladd
2014/01/24 23:03:03
add: "Also, it's fun to serve your Dart client app
mem
2014/01/24 23:55:05
Done.
|
| +The code you downloaded for this project contains a server. |
| +This step walks through the code for the server, |
| +which uses some interesting Dart APIs and |
| +two helpful pub packages. |
| + |
| +Links to the relevant API docs are provided in [Resources](#resources). |
| + |
| +### <i class="fa fa-anchor"> </i> Setting the path to the app. |
| + |
| +<div class="row"> <div class="col-md-7" markdown="1"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +Double click `bin/basic_http_server.dart` to open it. The beginning of |
| +the code is as follows: |
| + |
| +{% prettify dart %} |
| +import 'dart:io' show File, HttpServer, [[highlight]]Platform[[/highlight]]; |
| +import 'dart:async' show runZoned; |
| +import 'package:http_server/http_server.dart' show VirtualDirectory; |
| +import 'package:path/path.dart' show [[highlight]]join, dirname;[[/highlight]] |
| + |
| +void main() { |
| + [[highlight]]// Assumes the server lives in bin/ and that `pub build` ran.[[/highlight]] |
| + [[highlight]]var pathToBuild = join(dirname(Platform.script.toFilePath()),[[/highlight]] |
| + [[highlight]]'..', 'build');[[/highlight]] |
| + |
| + ... |
| +} |
| +{% endprettify %} |
| +</div> |
| + |
| +<div class="trydart-filename">basic_http_server.dart</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* This code assumes that `pub build` has run, because |
| + it relies on the `build` directory existing. |
| + |
| +* In the next step, you will configure a Heroku buildpack |
| + (a collection of scripts) |
| + that runs `pub build` when you upload your app. |
| + |
| +* This code uses `join` along with `dirname` to |
| + create a path to the `build` directory |
| + based on the path of the running script. |
| + |
| +* The top-level `Platform` object provides information about the |
| + environment in which the program is running. |
| + Here, the code gets the filepath to the program. |
| + |
| + {% comment %} non-breaking space required for bootstrap/markdown bogosity {% endcomment %} |
| + |
| +</div> </div> |
| + |
| +### <i class="fa fa-anchor"> </i> Serving `piratebadge.html`. |
| + |
| +<div class="row"> <div class="col-md-7" markdown="1"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +{% prettify dart %} |
| +import 'dart:io' show [[highlight]]File[[/highlight]], HttpServer, Platform; |
| +import 'dart:async' show runZoned; |
| +import 'package:http_server/http_server.dart' show [[highlight]]VirtualDirectory;[[/highlight]] |
| +import 'package:path/path.dart' show join, dirname; |
| + |
| +void main() { |
| + ... |
| + [[highlight]]var staticFiles = new VirtualDirectory(pathToBuild);[[/highlight]] |
| + [[highlight]]staticFiles.allowDirectoryListing = true;[[/highlight]] |
| + [[highlight]]staticFiles.directoryHandler = (dir, request) {[[/highlight]] |
| + [[highlight]]// Redirect directory-requests to piratebadge.html file.[[/highlight]] |
| + [[highlight]]var indexUri = new Uri.file(dir.path).resolve('piratebadge.html');[[/highlight]] |
| + [[highlight]]staticFiles.serveFile(new File(indexUri.toFilePath()), request);[[/highlight]] |
| + [[highlight]]};[[/highlight]] |
| + ... |
| +} |
| +{% endprettify %} |
| +</div> |
| + |
| +<div class="trydart-filename">basic_http_server.dart</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* The `VirtualDirectory` class from the `http_server` package |
| + provides a high-level interface for serving static files and directory listings to HttpRequests. |
| + |
| +* This code redirects directory requests to `piratebadge.html`, |
| + which is the main HTML file for this app. |
| + This approach works because the deployed app has only one directory. |
| + |
| +* The `serveFile` method serves the requested static file |
| + to the given HttpRequest object. |
| + |
| +* Without the `http_server` package, this code would be longer and more complex, |
| + because you would have to use the lower-level `HttpServer`, `HttpRequest`, |
| + and `HttpResponse` APIs. |
| + |
| + {% comment %} non-breaking space required for bootstrap/markdown bogosity {% endcomment %} |
| + |
| +</div> </div> |
| + |
| +### <i class="fa fa-anchor"> </i> Using variable port numbers. |
| + |
| +<div class="row"> <div class="col-md-7" markdown="1"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +{% prettify %} |
| +import 'dart:io' show File, HttpServer, [[highlight]]Platform[[/highlight]]; |
| +import 'dart:async' show runZoned; |
| +import 'package:http_server/http_server.dart' show VirtualDirectory; |
| +import 'package:path/path.dart' show join, dirname; |
| + |
| +void main() { |
| + ... |
| + [[highlight]]var portEnv = Platform.environment['PORT'];[[/highlight]] |
| + [[highlight]]var port = portEnv == null ? 9999 : int.parse(portEnv);[[/highlight]] |
| + ... |
| +} |
| +{% endprettify %} |
| +</div> |
| + |
| +<div class="trydart-filename">basic_http_server.dart</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* Heroku uses variable ports. Heroku sets the `$PORT` environment variable |
| + with the port number that your app should listen to. |
| + |
| +* This code uses the port specified in the `$PORT` environment variable, |
| + if present. Otherwise, it uses port 9999. |
| + |
| +* The `$PORT` environment variable might not be present if the server is running |
| + in a non-Heroku environment. |
| + |
| + {% comment %} non-breaking space required for bootstrap/markdown bogosity {% endcomment %} |
| + |
| +</div> </div> |
| + |
| + |
| +### <i class="fa fa-anchor"> </i> Using `runZoned()`. |
| + |
| +<div class="row"> <div class="col-md-7" markdown="1"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| + |
| +{% prettify dart %} |
| +import 'dart:io' show File, HttpServer, Platform; |
| +import 'dart:async' show [[highlight]]runZoned[[/highlight]]; |
| +import 'package:http_server/http_server.dart' show VirtualDirectory; |
| +import 'package:path/path.dart' show join, dirname; |
| + |
| +void main() { |
| + ... |
| + [[highlight]]runZoned(() {[[/highlight]] |
| + ... |
| + [[highlight]]},[[/highlight]] |
| + [[highlight]]onError: (e, stackTrace) => print('Oh noes! $e $stackTrace'));[[/highlight]] |
| +} |
| +{% endprettify %} |
| +</div> |
| + |
| +<div class="trydart-filename">basic_http_server.dart</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* `runZoned` helps provide stability to your program. |
| + It catches exceptions from all call stacks within its bounds, |
| + allowing your program to continue running in spite of errors. |
| + |
| + {% comment %} non-breaking space required for bootstrap/markdown bogosity {% endcomment %} |
| + |
| +</div> </div> |
| + |
| +### <i class="fa fa-anchor"> </i> Listening for HTTP requests. |
| + |
| +<div class="row"> <div class="col-md-7" markdown="1"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| + |
| +{% prettify dart %} |
| +import 'dart:io' show File, [[highlight]]HttpServer[[/highlight]], Platform; |
| +import 'dart:async' show runZoned; |
| +import 'package:http_server/http_server.dart' show VirtualDirectory; |
| +import 'package:path/path.dart' show join, dirname; |
| + |
| +void main() { |
| + ... |
| + runZoned(() { |
| + [[highlight]]HttpServer.bind('0.0.0.0', port).then((server) {[[/highlight]] |
| + [[highlight]]server.listen(staticFiles.serveRequest);[[/highlight]] |
| + [[highlight]]});[[/highlight]] |
| + }, |
| + onError: (e, stackTrace) => print('Oh noes! $e $stackTrace')); |
| +} |
| +{% endprettify %} |
| +</div> |
| + |
| +<div class="trydart-filename">basic_http_server.dart</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* `HttpServer.bind()` creates an HTTP server, which responds to HTTP requests |
| + for this app. |
| + |
| +* The server binds to a host `0.0.0.0`. |
| + which is a special address that is guaranteed to receive from any network socket. |
|
sethladd
2014/01/24 23:03:03
long line.
also, receive what?
mem
2014/01/24 23:55:05
Done.
|
| + If you don't know what specific IP to listen to, you can use 0.0.0.0. |
| + |
| +* The server listens for requests and uses the `VirtualDirectory` object |
| + named `staticFiles` to handle them. |
| + |
| + {% comment %} non-breaking space required for bootstrap/markdown bogosity {% endcomment %} |
|
sethladd
2014/01/24 23:03:03
long line
mem
2014/01/24 23:55:05
Done.
|
| + |
| +</div> </div> |
| + |
| + |
| +### <i class="fa fa-anchor"> </i> Run the server, run the app |
| + |
| +<div class="row"> <div class="col-md-7" markdown="1"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +In Dart Editor, |
| +right click `bin/basic_http_server.dart` and select `Run`. |
| +Dart Editor brings up a new output pane in which the server |
| +displays its output, if any. |
| + |
| +Now, type `0.0.0.0:9999` in the URL text field of any browser. |
|
sethladd
2014/01/24 23:03:03
how about: "Now, open `http://0.0.0.0:9999` in yo
mem
2014/01/24 23:55:05
Done.
|
| +The app appears and you can generate pirate names. |
| + |
| +<strong>Leave the server running.</strong> |
| + |
| +</div> |
| + |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* 0.0.0.0:9999 requests the root directory of that host and port. |
| + The static file server resolves that request to `piratebadge.html` |
| + and returns the contents of that file. |
| + |
| +* 0.0.0.0:9999 requests work only on your local machine. |
| + Another machine cannot run your app using that URL. |
| + In [Step 5](#step-five), you deploy your app to Heroku, |
| + which gives you a public URL. |
| + |
| + {% comment %} non-breaking space required for bootstrap/markdown bogosity {% endcomment %} |
| + |
| +</div> </div> |
| + |
| +<hr> |
| + |
| +##Step 4: Inspect your app on a mobile device {#step-four} |
| + |
| +Before deploying your app, |
| +you can use the Chrome DevTools to check, debug, and modify |
| +your app on a mobile device. |
| +DevTools can debug Android devices natively |
| +and other devices using |
| +[Mobile Emulation](https://developers.google.com/chrome-developer-tools/docs/mobile-emulation). |
| +This section shows you how to use DevTools with your app on an Android device. |
| + |
| +You don't need to do this step to deploy your app. |
| +You can skip and move on to [Step 5](#step-five). |
| +However, this does help you to test and debug your app on mobile devices |
| +and it's pretty cool. |
| + |
| +### <i class="fa fa-anchor"> </i> Set up your computer and device |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +Follow the instructions at |
| +[Remote Debugging Chrome on Android](https://developers.google.com/chrome-developer-tools/docs/remote-debugging) |
| +to set up your device, Chrome, and your computer. |
| + |
| +</div> |
| + |
| +### <i class="fa fa-anchor"> </i> Run the app on your mobile device |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +Make sure your server is still running from [Step 3](#step-three). |
| + |
| +On your mobile device, bring up Chrome, |
| +and type the `0.0.0.0:9999` URL into the URL text field. |
|
sethladd
2014/01/24 23:03:03
"open http://0.0.0.0:9999 in your browser.
mem
2014/01/24 23:55:05
Done.
|
| + |
| +<img src="images/calebthebrave.png" height="400"> |
| + |
| +</div> |
| + |
| +### <i class="fa fa-anchor"> </i> Bring up Devices page |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +In Chrome on your computer, |
| +click the Android icon at the right side of any window |
| +and select **View Inspection Targets**. |
| +If the Android icon is not there, |
| +then the mobile device or your computer is not properly connected or setup. |
| +Refer back to the |
| +[Remote Debugging Chrome on Android](https://developers.google.com/chrome-developer-tools/docs/remote-debugging) |
| +instructions. |
| + |
| + |
| + |
| +The Devices page appears and an entry for your app appears. |
| + |
| + |
| + |
| +</div> |
| + |
| +### <i class="fa fa-anchor"> </i> Bring up DevTools for the app |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +On the Devices page, click `inspect` under the entry for your app. |
| +A DevTools window appears that is attached to your app running |
| +on the mobile device. |
|
sethladd
2014/01/24 23:03:03
can you double-clarify what's going on?
"You are
mem
2014/01/24 23:55:05
Done.
|
| + |
| + |
| + |
| +</div> |
| + |
| +### <i class="fa fa-anchor"> </i> Experiment with changing the app |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +Experiment by modifying the font size or color. |
|
sethladd
2014/01/24 23:03:03
clarify that you mean for them to use dev tools to
mem
2014/01/24 23:55:05
Done.
|
| +The change happens instantly on your mobile device. |
| + |
| +</div> |
| + |
| +### <i class="fa fa-anchor"> </i> Save your changes |
|
sethladd
2014/01/24 23:03:03
maybe drop this section? it sort of implies you ca
mem
2014/01/24 23:55:05
Done.
|
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +If you want, make any permanent changes to your source code and build the app again. |
| + |
| +</div> |
| + |
| + |
| +##Step 5: Deploy to Heroku {#step-five} |
| + |
| +In this step, you deploy your server and app to Heroku. |
|
sethladd
2014/01/24 23:03:03
maybe talk about why heroku? heroku is a cloud hos
mem
2014/01/24 23:55:05
Done.
|
| + |
| +### <i class="fa fa-anchor"> </i> Get Heroku and a Heroku account |
| + |
| +<div class="row"> <div class="col-md-7" markdown="1"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +Follow Steps 1, 2, and 3 at |
| +[Getting Started with Heroko](https://devcenter.heroku.com/articles/quickstart) |
|
sethladd
2014/01/24 23:03:03
typo: heroku
mem
2014/01/24 23:55:05
Done.
|
| +to download the Heroku tools and get an account with Heroku. |
| + |
| +</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* Now you can deploy your app to Heroku. |
|
sethladd
2014/01/24 23:03:03
This seems like a status update, not a "what this
mem
2014/01/24 23:55:05
Done.
|
| + |
| + {% comment %} non-breaking space required for bootstrap/markdown bogosity {% endcomment %} |
| + |
| +</div> </div> |
| + |
| + |
| +### <i class="fa fa-anchor"> </i> Create a `Procfile` |
| + |
| +<div class="row"> <div class="col-md-7" markdown="1"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +In the `deploy-codelab` directory, create a file |
| +named `Procfile` and add the following line to it. |
| + |
| +{% prettify bash %} |
| + |
| +web: ./dart-sdk/bin/dart bin/basic_http_server.dart |
| + |
| +{% endprettify %} |
| + |
| +</div> |
| + |
| +<div class="trydart-filename">Procfile</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* A `Procfile` tells Heroku what part of your app can be executed. |
| + |
| +* The `Procfile` for this example defines a web process type |
| + in which the dart VM runs the static file server. |
| + |
| + {% comment %} non-breaking space required for bootstrap/markdown bogosity {% endcomment %} |
| + |
| +</div> </div> |
| + |
| + |
| +### <i class="fa fa-anchor"> </i> Commit your changes to your local `deploy-codelab` git repo |
|
sethladd
2014/01/24 23:03:03
couple things to define:
what is git?
what is a g
mem
2014/01/24 23:55:05
Done.
|
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +`git` is the means for deploying apps to Heroku. |
| +Before you can push an app to Heroku, |
| +you need to initialize a local `git` repo and commit your files to it. |
| +</div> |
| + |
| +<div class="row"> <div class="col-md-7" markdown="1"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +{% prettify bash %} |
| +$ cd deploy-codelab |
| +$ git init |
| +$ git add -A . |
| +$ git commit -am "Hoist the mizzen!" |
| +$ |
|
sethladd
2014/01/24 23:03:03
blank prompt?
mem
2014/01/24 23:55:05
Done.
|
| +{% endprettify %} |
| + |
| +</div> |
| + |
| +<div class="trydart-filename">terminal</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* First, create a local repo with `git init`. |
| + |
| +* Next, add all of the files in `deploy-codelab` to it. |
| + |
| +* Finally, commit the new files in the `build` directory to your local |
| + git repo. |
| + |
| + {% comment %} non-breaking space required for bootstrap/markdown bogosity {% endcomment %} |
| + |
| +</div> </div> |
| + |
| +### <i class="fa fa-anchor"> </i> Create a Heroku app and configure it. |
| + |
| +<div class="row"> <div class="col-md-7" markdown="1"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +<strong>Important:</strong> Replace |
| +`myfirstdartappforheroku` with something **unique**. |
| + |
| +{% prettify bash %} |
| +$ heroku create [[highlight]]myfirstdartappforheroku[[/highlight]] -s cedar |
| +$ heroku labs:enable user-env-compile |
| +$ heroku config:set DART_SDK_URL=https://github.com/selkhateeb/heroku-vagrant-dart-build/releases/download/latest/dart-sdk.tar |
| +$ heroku config:add BUILDPACK_URL=https://github.com/igrigorik/heroku-buildpack-dart.git |
| +$ |
| +{% endprettify %} |
| + |
| +</div> |
| + |
| +<div class="trydart-filename">terminal</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* First, create a Heroku app. |
| + Provide it with a **unique** name (not `myfirstdartappforheroku`). |
| + |
| +* Next, enable `user-env-compile` so that environment variables |
| + can be passed to the build script during deploy. |
| + |
| +* Official builds of Dart do not support Heroku due to mismatched glibc |
| + versions. In this code lab, |
| + you'll use the (unsupported) [Vagrant Dart Build](https://github.com/selkhateeb/heroku-vagrant-dart-build), |
| + which is a special build of the Dart SDK that is compatible with Heroku. |
| + |
| +* A buildpack extends Heroku. The buildpack used here extends Heroku |
| + to support Dart apps. The location of the buildpack |
| + is specified with the `BUILDPACK_URL`. |
| + |
| + {% comment %} non-breaking space required for bootstrap/markdown bogosity {% endcomment %} |
| + |
| +</div> </div> |
| + |
| +### <i class="fa fa-anchor"> </i> Push your app to Heroku |
| + |
| +<div class="row"> <div class="col-md-7" markdown="1"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +Some output has been replaced with ellipses to save space, |
| +but the output from the push command will look something this: |
| + |
| + |
| +{% prettify bash %} |
| +$ [[highlight]]git push heroku master[[/highlight]] |
| +Initializing repository, done. |
| + |
| +... |
| +-----> Fetching custom git buildpack... done |
| +-----> Dart app detected |
| +... |
| +Dart VM version: 1.0.0.5_r30248_vagrant (Thu Nov 14 13:43:29 2013) on "linux_x64" |
| +... |
| +*** Running pub build |
| +Building with "pub build" |
| +Building deploy_codelab.................... |
| +[Info in Dart2JS]: |
| +Generated deploy_codelab|web/piratebadge.dart.js (97701 characters) in 0:01:19.685114 |
| +Built 6 files! |
| +... |
| +-----> Launching... done, v6 |
| + [[highlight]]http://myfirstdartappforheroku.herokuapp.com deployed to Heroku[[/highlight]] |
| + |
| +To git@heroku.com:myfirstdartappforheroku.git |
| + * [new branch] master -> master |
| +$ |
| +{% endprettify %} |
| + |
| + |
| +</div> |
| + |
| +<div class="trydart-filename">terminal</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| + |
| +* Your local `git` repository becomes associated with a remote Heroku repository, |
| + usually named `heroku`, when you push. |
| + |
| +* When you push, Heroku runs the buildpack that you specified. |
| + |
| +* In addition to other tasks, this buildpack runs `pub build`. |
| + |
| +* When the push is finished, the process displays a URL for your app. |
| + |
| + {% comment %} non-breaking space required for bootstrap/markdown bogosity {% endcomment %} |
| + |
| +</div> </div> |
| + |
| +### <i class="fa fa-anchor"> </i> Specify the scale |
| + |
| +<div class="row"> <div class="col-md-7" markdown="1"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +{% prettify bash %} |
| +$ heroku ps:scale web=1 |
|
sethladd
2014/01/24 23:03:03
two spaces after scale
mem
2014/01/24 23:55:05
Done.
|
| +$ |
| +{% endprettify %} |
| + |
| +</div> |
| + |
| +<div class="trydart-filename">terminal</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* Scale to one _dyno_, which is a Heroku lightweight container |
| + that runs a single user-specified command. |
| + |
| + {% comment %} non-breaking space required for bootstrap/markdown bogosity {% endcomment %} |
| + |
| +</div> </div> |
| + |
| +<hr> |
| + |
| +##Step 6: Run the app on the web and on a mobile device {#step-six} |
| + |
| +Now that your app is deployed, you can run it on the web |
| +and on a mobile device. |
| + |
| +### <i class="fa fa-anchor"> </i> Run the app in a browser |
| + |
| +<div class="row"> <div class="col-md-7" markdown="1"> |
| + |
| +<iframe class="running-app-frame" |
| + style="height:220px;width:550px;" |
| + src="/codelabs/darrrt/examples/6-piratebadge/piratebadge.html"> |
| +</iframe> |
| + |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* Use the URL displayed by the previous step to visit your app: |
| + `http://myfirstdartappforheroku.herokuapp.com` |
| + |
| +</div> </div> |
| + |
| + |
| +### <i class="fa fa-anchor"> </i> Run the app on a mobile device |
| + |
| +<div class="row"> <div class="col-md-7" markdown="1"> |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +<img src="images/calebthebrave.png" height="400"> |
| + |
| +</div> |
| + |
| +</div> <div class="col-md-5" markdown="1"> |
| + |
| +<i class="fa fa-key key-header"> </i> <strong> Key Information </strong> |
| + |
| +* Use the URL from the previous step to load the app |
| + into a browser on your mobile device. |
| + `http://myfirstdartappforheroku.herokuapp.com` |
| + |
| + {% comment %} non-breaking space required for bootstrap/markdown bogosity {% endcomment %} |
| + |
| +</div> </div> |
| + |
| + |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| +</div> |
| + |
| +<hr> |
| + |
| +##Resources {#resources} |
| + |
| +For more information about the tools and libraries used |
| +in this code lab, check out these resources. |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +#### SDK libraries, classes, and functions |
| + |
| +* The API docs for the |
| +<a href="https://api.dartlang.org/dart_io/File.html" target="_blank">File</a>, |
| +<a href="https://api.dartlang.org/dart_io/HttpServer.html" target="_blank">HttpServer</a>, and |
| +<a href="https://api.dartlang.org/dart_io/Platform.html" target="_blank">Platform</a> |
| +classes from the |
| +<a href="https://api.dartlang.org/dart_io.html" target="_blank">dart:io</a> |
| +library. |
| +* The API docs for the |
| +<a href="https://api.dartlang.org/dart_async.html#runZoned" target="_blank">runZoned()</a> |
| +function from the |
| +<a href="https://api.dartlang.org/dart_async.html" target="_blank">dart:async</a> library. |
| + |
| +#### Classes and functions from pub packages |
| + |
| +* The code for the |
| +<a href="https://pub.dartlang.org/packages/http_server">http_server</a> pub package, |
| +in particular |
| +<a href="https://api.dartlang.org/http_server/VirtualDirectory.html" target="_blank">VirtualDirectory</a> |
| +class. |
| +* The code for the |
| +<a href="http://pub.dartlang.org/packages/path">path</a> pub package, |
| +in particular the |
| +<a href="https://api.dartlang.org/path.html#join" target="_blank">join()</a> |
| +and |
| +<a href="https://api.dartlang.org/path.html#dirname" target="_blank">dirname()</a> |
| +functions. |
| + |
| +#### Heroku tools |
| + |
| +* The <a href="https://devcenter.heroku.com/">Heroku Dev Center</a>. |
| +* The Heroku-compatible build of the Dart SDK: |
| +[heroku-vagrant-dart-build](https://github.com/selkhateeb/heroku-vagrant-dart-build). |
| +* The Heroku buildpack for Dart: |
| +[heroku-buildpack-dart](https://github.com/igrigorik/heroku-buildpack-dart). |
| + |
| +#### The example code |
| + |
| +* The [deploy-codelab](https://github.com/dart-lang/deploy-codelab) |
| +example code. |
| + |
| +</div> |
| + |
| +<hr> |
| + |
| +##What next? {#what-next} |
| + |
| +Now that your app is deployed for the world to use, |
| +what do you do now? |
| +Here are some suggestions. |
| + |
| +### <i class="fa fa-anchor"> </i> Share your app with the world! |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +Share your Heroku URL with your followers and circles. |
| + |
| +* <a href="https://twitter.com/share" class="twitter-share-button" data-text="Arrr! I've deployed me app. http://dartlang.org/codelab/deploy/" data-count="none" data-hashtags="dartlang">Tweet</a> |
| +<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script> |
| + |
| +{% comment %} |
| +* <p class="share-button twitter"> |
| +<a href="https://twitter.com/share" |
| + class="twitter-share-button external-link" |
| + data-count="none" |
| + data-text="Arrr! I've deployed me app. http://dartlang.org/codelab/deploy/" |
| + data-hashtags="dartlang">Tweet</a> </p> |
| +{% endcomment %} |
| + |
| +* <p> |
| +<script src="https://apis.google.com/js/plusone.js"></script> |
| +<g:plus action="share"></g:plus> </p> |
| + |
| +</div> |
| + |
| +### <i class="fa fa-anchor"> </i> Jump to another ship. |
| + |
| +<div class="trydart-step-details" markdown="1"> |
| + |
| +* If you never went through the [Avast, Ye Pirates](/codelabs/darrrt/) code lab, do it now. |
| +* For more command-line application and server code, |
| + visit [Dart by Example](/dart-by-example/). |
| +* Play with some [samples](/samples/). |
| +* Try the [tutorials](/docs/tutorials/), |
| + in particular the [command-line app tutorial](/docs/tutorials/cmdline/). |
| +* Go write some awesome code. |
| + |
| +</div> |
| + |