569 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			569 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| include _util-fns
 | |
| 
 | |
| :marked
 | |
|   Let's start from zero and build a super simple Angular application in JavaScript.
 | |
| 
 | |
| .callout.is-helpful
 | |
|   header Don't want JavaScript?
 | |
|   :marked
 | |
|     Although we're getting started in JavaScript, you can also write Angular apps
 | |
|     in TypeScript and Dart by selecting either of those languages from the combo-box in the banner.
 | |
| 
 | |
| .l-main-section
 | |
| :marked
 | |
|   ## See It Run!
 | |
| 
 | |
|   Running the <live-example></live-example>
 | |
|   is the quickest way to see an Angular app come to life.
 | |
|   
 | |
|   Clicking that link fires up a browser, loads the sample in [plunker](http://plnkr.co/ "Plunker"),
 | |
|   and displays a simple message:
 | |
| 
 | |
| figure.image-display
 | |
|   img(src='/resources/images/devguide/quickstart/hello-angular.png' alt="Output of quickstart app")
 | |
| :marked
 | |
|   Here is the file structure:
 | |
| .filetree
 | |
|   .file angular-quickstart
 | |
|   .children
 | |
|     .file app
 | |
|     .children
 | |
|       .file app.component.js
 | |
|       .file app.module.js
 | |
|       .file main.js
 | |
|     .file index.html
 | |
|     .file styles.css
 | |
| :marked
 | |
|   Functionally, it's an `index.html`, `styles.css` and three JavaScript files in an `app/` folder.
 | |
|   We can handle that!
 | |
|   
 | |
|   Of course we won't build  many apps that only run in plunker. 
 | |
|   Let's follow a process that's closer to what we'd do in real life.
 | |
|   
 | |
|   1. Set up our development environment
 | |
|   1. Write the Angular root component for our app
 | |
|   1. Add an Angular Module
 | |
|   1. Bootstrap it to take control of the main web page
 | |
|   1. Write the main page (`index.html`)
 | |
|   1. Add some CSS (`styles.css`)
 | |
|   
 | |
| .l-sub-section
 | |
|   :marked
 | |
|     We really can build the QuickStart from scratch in five minutes 
 | |
|     if we follow the instructions and ignore the commentary.
 | |
|     
 | |
|     Most of us will be interested in the "why" as well as the "how" and that will take longer.
 | |
| :marked
 | |
| 
 | |
| .l-main-section
 | |
| :marked
 | |
|   ## Development Environment
 | |
|   
 | |
|   We'll need a place to stand (the application project folder), some libraries 
 | |
|   and your editor of choice.
 | |
| 
 | |
|   ### Create a new project folder
 | |
|   
 | |
| code-example(format="").
 | |
|   mkdir angular-quickstart
 | |
|   cd    angular-quickstart
 | |
| :marked
 | |
|   ### Add the libraries we need
 | |
|   
 | |
|   We recommend the **npm** package manager for acquiring and managing our development libraries.
 | |
| 
 | |
| .l-sub-section
 | |
|   :marked
 | |
|     Don't have npm?
 | |
|     [Get it now](https://docs.npmjs.com/getting-started/installing-node "Installing Node.js and updating npm")
 | |
|     because we're going to use it now and repeatedly throughout this documentation.
 | |
| :marked
 | |
|   Add a **package.json** file to the project folder and copy/paste the following:
 | |
| +makeJson('quickstart/js/package.1.json', null, 'package.json')(format=".")  
 | |
| 
 | |
| .l-sub-section
 | |
|   :marked
 | |
|     Itching to know the details? We explain in the [appendix below](#package-json)  
 | |
| :marked
 | |
|   Install these packages by opening a terminal window (command window in Windows) and
 | |
|   running this npm command.
 | |
| code-example(format="").
 | |
|   npm install
 | |
| :marked
 | |
| .l-sub-section
 | |
|   :marked
 | |
|     Scary <span style="color:red; font-weight: bold">error messages in red</span> may appear **during** install. 
 | |
|     Ignore them. The install will succeed. See the [appendix below](#npm-errors) for more information.
 | |
| 
 | |
| .l-main-section
 | |
| :marked
 | |
|   ## Our First Angular Component
 | |
|   
 | |
|   The *Component* is the most fundamental of Angular concepts. 
 | |
|   A component manages a view - a piece of the web page where we display information
 | |
|   to the user and respond to user feedback.
 | |
|   
 | |
|   Technically, a component is a class that controls a view template.
 | |
|   We'll write a lot of them as we build Angular apps. This is our first attempt
 | |
|   so we'll keep it ridiculously simple.
 | |
|   
 | |
|   ### Create an application source sub-folder
 | |
|   
 | |
|   We like to keep our application code in a sub-folder off the root called `app/`.
 | |
|   Execute the following command in the console window.
 | |
| code-example(format="").
 | |
|   mkdir app
 | |
|   cd    app
 | |
| :marked
 | |
|   ### Add the component file
 | |
|   Now add a file named **app.component.js** and paste the following lines:
 | |
| +makeExample('quickstart/js/app/app.component.js', null, 'app/app.component.js')(format=".")
 | |
| :marked
 | |
|   We're creating a visual component named **`AppComponent`** by chaining the
 | |
|   `Component` and `Class` methods that belong to the **global Angular core namespace, `ng.core`**.
 | |
|   
 | |
| +makeExample('quickstart/js/app/app.component.js', 'ng-namespace-funcs', 'app/app.component.js ' +
 | |
| '(component schema)')(format=".")
 | |
| 
 | |
| :marked
 | |
|   The **`Component`** method takes a configuration object with three
 | |
|   properties. The **`Class`** method is where we implement the component itself,
 | |
|   giving it properties and methods that bind to the view and whatever
 | |
|   behavior is appropriate for this part of the UI.
 | |
|   
 | |
|   Let's review this file in detail.
 | |
| 
 | |
|   ### Modules
 | |
|   Angular apps are modular. They consist of many files each dedicated to a purpose.
 | |
|   
 | |
|   ES5 JavaScript doesn't have a native module system.
 | |
|   There are several popular 3rd party module systems we could use.
 | |
|   Instead, for simplicity and to avoid picking favorites,
 | |
|   we'll create a single global namespace for our application.
 | |
|   
 | |
|   We'll call it `app` and we'll add all of our code artifacts to this one global object.
 | |
|   
 | |
|   We don't want to pollute the global namespace with anything else.
 | |
|   So within each file we surround the code in an IIFE ("Immediately Invoked Function Expression").
 | |
|   
 | |
| +makeExample('quickstart/js/app/app.component.js', 'iife', 'app/app.component.js (IIFE)')(format=".")
 | |
|   
 | |
| :marked
 | |
|   We pass the global `app` namespace object into the IIFE, 
 | |
|   taking care to initialize it with an empty object if it doesn't yet exist.
 | |
|   
 | |
|   Most application files *export* one thing by adding that thing to the `app` namespace.
 | |
|   Our `app.component.js` file exports the `AppComponent`.
 | |
|   
 | |
| +makeExample('quickstart/js/app/app.component.js', 'export', 'app/app.component.js (export)')(format=".")
 | |
|   
 | |
| :marked
 | |
|   A more sophisticated application would have child components that descended from
 | |
|   `AppComponent` in a visual tree. 
 | |
|   A more sophisticated app would have more files and modules, at least as many as it had components.
 | |
|   
 | |
|   Quickstart isn't sophisticated; one component is all we need.
 | |
|   Yet modules play a fundamental organizational role in even this small app.
 | |
|   
 | |
|   Modules rely on other modules. In JavaScript Angular apps, when we need something
 | |
|   provided by another module, we get it from the `app` object. 
 | |
|   When another module needs to refer to `AppComponent`, it gets it from the `app.AppComponent` like this:
 | |
|     
 | |
| +makeExample('quickstart/js/app/app.module.js', 'import', 'app/app.module.js (import)')(format=".")
 | |
| 
 | |
| :marked
 | |
|   Angular is also modular. It is a collection of library modules. 
 | |
|   Each library is itself a module made up of several, related feature modules.
 | |
|   
 | |
|   When we need something from Angular, we use the `ng` object.
 | |
|   
 | |
| :marked
 | |
|   ### The Class definition object
 | |
|   At the bottom of the file is an empty, do-nothing class definition object for 
 | |
|   our `AppComponent` class.
 | |
|   When we're ready to build a substantive application, 
 | |
|   we can expand this object with properties and application logic. 
 | |
|   Our `AppComponent` class has nothing but an empty constructor because we 
 | |
|   don't need it to do anything in this QuickStart.
 | |
|   
 | |
| +makeExample('quickstart/js/app/app.component.js', 'class','app.component.js (class)')(format=".")  
 | |
|   
 | |
| :marked
 | |
|   ### The Component definition object
 | |
|   `ng.core.Component()` tells Angular that this class definition object
 | |
|    *is an Angular component*.
 | |
|   The configuration object passed to the `ng.core.Component()` method has two
 | |
|   fields, a `selector` and a `template`.
 | |
|   
 | |
| +makeExample('quickstart/js/app/app.component.js', 'component','app.component.js (component)')(format=".")    
 | |
| 
 | |
| :marked
 | |
|   The `selector` specifies a simple CSS selector for a host HTML element named `my-app`.
 | |
|   Angular creates and displays an instance of our `AppComponent`
 | |
|   wherever it encounters a `my-app` element in the host HTML.
 | |
|   
 | |
| .alert.is-helpful
 | |
|   :marked
 | |
|     Remember the `my-app` selector! We'll need that information when we write our `index.html`
 | |
| :marked
 | |
|   The `template` property holds the component's companion template.
 | |
|   A template is a form of HTML that tells Angular how to render a view.
 | |
|   Our template is a single line of HTML announcing "Hello Angular!".
 | |
|   
 | |
|   Now we need something to tell Angular to load this component.
 | |
| 
 | |
|   ### Add an NgModule
 | |
| 
 | |
|   Angular apps are composed of [Angular Modules](guide/ngmodule.html) that 
 | |
|   snuggly contain all our components and everything else we need for our app.
 | |
| 
 | |
|   Create the `app/app.module.js` file with the following content:
 | |
| 
 | |
| +makeExample('quickstart/js/app/app.module.js', null, 'app/app.module.js')
 | |
| 
 | |
| .l-sub-section
 | |
|   :marked
 | |
|     Read more about the `NgModule` configuration in the [appendix below](#ngmodule).
 | |
| 
 | |
| :marked
 | |
|   ### Bootstrap it!
 | |
| 
 | |
|   Add a new file , `main.js`, to the `app/` folder as follows:
 | |
| +makeExample('quickstart/js/app/main.js', null, 'app/main.js')(format=".")
 | |
| :marked
 | |
|   We need two things to launch the application:
 | |
|   1. Angular's `platformBrowserDynamic().bootstrapModule` function
 | |
|   1. The application root module that we just wrote.
 | |
|   
 | |
|   We have them both in our 'namespaces'. 
 | |
|   Then we call `bootstrapModule`, passing in the **root app module**, `AppModule`.
 | |
|  
 | |
| .l-sub-section
 | |
|   :marked
 | |
|     Learn why we need `bootstrapModule` from `ng.platformBrowserDynamic`
 | |
|     and why we create a separate js files in the [appendix below](#main).
 | |
| :marked
 | |
|   We've asked Angular to launch the app in a browser with our component at the root.
 | |
|   Where will Angular put it? 
 | |
| 
 | |
| .l-main-section
 | |
| :marked
 | |
|   ## Add the `index.html`
 | |
|   
 | |
|   Angular displays our application in a specific location on our `index.html`.
 | |
|   It's time to create that file.
 | |
| 
 | |
|   We won't put our `index.html` in the `app/` folder. 
 | |
|   We'll locate it **up one level, in the project root folder**.
 | |
|   
 | |
| code-example(format="").
 | |
|   cd ..
 | |
| :marked
 | |
|   Now create the`index.html` file and paste the following lines:
 | |
| +makeExample('quickstart/js/index.html', null, 'index.html')(format=".")
 | |
| :marked
 | |
|   There are three noteworthy sections of HTML:
 | |
| 
 | |
|   1. We load the JavaScript libraries we need; learn about them [below](#libraries).
 | |
| 
 | |
|   2. We load our JavaScript files.
 | |
| 
 | |
|   3. We add the `<my-app>` tag in the `<body>`. **This is where our app lives!**
 | |
|   
 | |
|   When Angular calls the `bootstrapModule` function in `main.js`,
 | |
|   it reads the `AppModule` metadata, sees that `AppComponent` is the bootstrap component, 
 | |
|   finds the `my-app` selector, locates an element tag named `my-app`,
 | |
|   and renders our application's view between those tags.
 | |
| 
 | |
| :marked
 | |
|   ### Add some style
 | |
|   Styles aren't essential but they're nice, and `index.html` assumes we have
 | |
|   a stylesheet called `styles.css`.
 | |
| 
 | |
|   Create a `styles.css` file in the *#{_indexHtmlDir}* folder and start styling, perhaps with the minimal
 | |
|   styles shown below. For the full set of master styles used by the documentation samples,
 | |
|   see [styles.css](https://github.com/angular/angular.io/blob/master/public/docs/_examples/styles.css).
 | |
| +makeExample('quickstart/js/styles.1.css', null, 'styles.css')(format=".")
 | |
| 
 | |
| .l-main-section
 | |
| :marked
 | |
|   ## Run!
 | |
|   
 | |
|   Open a terminal window and enter this command:
 | |
| code-example(format="").
 | |
|   npm start
 | |
| :marked
 | |
|   That command runs a static server called **lite-server** that loads `index.html` in a browser
 | |
|   and refreshes the browser when application files change.
 | |
| 
 | |
|   In a few moments, a browser tab should open and display
 | |
| 
 | |
| figure.image-display
 | |
|   img(src='/resources/images/devguide/quickstart/hello-angular.png' alt="Output of quickstart app")
 | |
| 
 | |
| :marked
 | |
|   Congratulations!  We are in business.
 | |
| 
 | |
| .alert.is-helpful
 | |
|   :marked
 | |
|     If you see `Loading...` displayed instead, see the
 | |
|     [Browser ES2015 support appendix](#es6support).
 | |
| :marked
 | |
|   ### Make some changes
 | |
|   
 | |
|   Try changing the message to "Hello Angular 2!".
 | |
|   
 | |
|   `lite-server` is watching, so it should detect the change,
 | |
|   refresh the browser, and display the revised message.
 | |
| 
 | |
|   It's a nifty way to develop an application!
 | |
|   
 | |
|   We close the terminal window when we're done to terminate the server.
 | |
| 
 | |
| .l-main-section
 | |
| :marked
 | |
|   ## Final structure
 | |
|   Our final project folder structure looks like this:
 | |
| .filetree
 | |
|   .file angular-quickstart
 | |
|   .children
 | |
|     .file node_modules
 | |
|     .file app
 | |
|     .children
 | |
|       .file app.component.js
 | |
|       .file app.module.js
 | |
|       .file main.js
 | |
|     .file index.html
 | |
|     .file package.json
 | |
|     .file styles.css
 | |
| :marked
 | |
|   And here are the files:
 | |
| +makeTabs(`
 | |
|     quickstart/js/app/app.component.js,
 | |
|     quickstart/js/app/app.module.js,
 | |
|     quickstart/js/app/main.js,
 | |
|     quickstart/js/index.html,
 | |
|     quickstart/js/package.1.json,
 | |
|     quickstart/js/styles.1.css
 | |
|   `,null,
 | |
|   `app/app.component.js,
 | |
|   app/app.module.js,
 | |
|   app/main.js,
 | |
|   index.html,
 | |
|   package.json,
 | |
|   styles.css`)
 | |
| :marked
 | |
| 
 | |
| .l-main-section
 | |
| :marked
 | |
|   ## Wrap Up
 | |
|   Our first application doesn't do much. It's basically "Hello, World" for Angular.
 | |
| 
 | |
|   We kept it simple in our first pass: we wrote a little Angular component,
 | |
|   we added some JavaScript libraries to `index.html`, and launched with a
 | |
|   static file server. That's about all we'd expect to do for a "Hello, World" app.
 | |
| 
 | |
|   **We have greater ambitions.**
 | |
| 
 | |
|   The good news is that the overhead of setup is (mostly) behind us. 
 | |
|   We'll probably only touch the `package.json` to update libraries.
 | |
|   Besides adding in the script files for our app 'modules',
 | |
|   we'll likely open `index.html` only if we need to add a library or some css stylesheets.
 | |
| 
 | |
|   We're about to take the next step and build a small application that 
 | |
|   demonstrates the great things we can build with Angular.
 | |
| 
 | |
|   Join us on the [Tour of Heroes Tutorial](./tutorial)!
 | |
| 
 | |
| 
 | |
| .l-main-section
 | |
| :marked
 | |
|   ## Appendices
 | |
|   The balance of this chapter is a set of appendices that
 | |
|   elaborate some of the points we covered quickly above.
 | |
|   
 | |
|   There is no essential material here. Continued reading is for the curious.
 | |
| 
 | |
| <a id="ie-polyfills"></a>
 | |
| <a id="es6support"></a>
 | |
| <a id="libraries"></a>
 | |
| .l-main-section
 | |
| :marked
 | |
|   ### Appendix: Libraries
 | |
|   We loaded the following scripts
 | |
| +makeExample('quickstart/js/index.html', 'libraries', 'index.html')(format=".")
 | |
| :marked
 | |
|   We began with an Internet Explorer polyfill. 
 | |
|   IE requires a polyfill to run
 | |
|   an application that relies on ES2015 promises and dynamic module loading.
 | |
|   Most applications need those capabilities and most applications
 | |
|   should run in Internet Explorer.
 | |
| 
 | |
|   Next are the polyfills for Angular, `zone.js` and `Reflect.js`,
 | |
|   followed by the Reactive Extensions RxJS library.
 | |
| .l-sub-section
 | |
|   :marked
 | |
|     Our QuickStart doesn't use the Reactive Extensions 
 | |
|     but any substantial application will want them
 | |
|     when working with observables.
 | |
|     We added the library here in QuickStart so we don't forget later.
 | |
| :marked
 | |
|   Finally, we loaded the web development version of Angular itself.
 | |
| 
 | |
|   We'll make different choices as we gain experience and
 | |
|   become more concerned about production qualities such as
 | |
|   load times and memory footprint.  
 | |
| .l-main-section
 | |
| :marked
 | |
| 
 | |
| 
 | |
| .l-main-section
 | |
| :marked
 | |
|   <a id="package-json"></a>
 | |
|   ### Appendix: package.json
 | |
| 
 | |
|   [npm](https://docs.npmjs.com/) is a popular package manager and Angular application developers rely on it
 | |
|   to acquire and manage the libraries their apps require.
 | |
|   
 | |
|   We specify the packages we need in an npm [package.json](https://docs.npmjs.com/files/package.json) file.
 | |
|   
 | |
|   The Angular team suggests the packages listed in the `dependencies` and `devDependencies`
 | |
|   sections listed in this file:
 | |
| 
 | |
| +makeJson('quickstart/js/package.1.json',{ paths: 'dependencies, devDependencies'}, 'package.json (dependencies)')(format=".") 
 | |
| :marked
 | |
| .l-sub-section
 | |
|   :marked
 | |
|     There are other possible package choices. 
 | |
|     We're recommending this particular set that we know work well together. 
 | |
|     Play along with us for now. 
 | |
|     Feel free to make substitutions later to suit your tastes and experience.
 | |
| :marked
 | |
|   A `package.json` has an optional **scripts** section where we can define helpful
 | |
|   commands to perform development and build tasks. 
 | |
|   We've included a number of such scripts in our suggested `package.json`:
 | |
| +makeJson('quickstart/js/package.1.json',{ paths: 'scripts'}, 'package.json (scripts)')(format=".") 
 | |
| :marked
 | |
|   We've seen how we can run the server with this command:
 | |
| code-example(format="").
 | |
|   npm start
 | |
| :marked
 | |
|   We are using the special `npm start` command, but all it does is run `npm run lite`.
 | |
|   
 | |
|   We execute npm scripts in that manner: `npm run` + *script-name*. Here's what these scripts do:
 | |
|   
 | |
|   * `npm run lite` - run the [lite-server](https://www.npmjs.com/package/lite-server), 
 | |
|   a light-weight, static file server, written and maintained by [John Papa](http://johnpapa.net/) 
 | |
|   with excellent support for Angular apps that use routing.
 | |
| 
 | |
| 
 | |
| .l-main-section
 | |
| :marked
 | |
|   <a id="npm-errors"></a>
 | |
|   ### Appendix: npm errors and warnings
 | |
|   
 | |
|   All is well if there are no console messages starting with `npm ERR!` *at the end* of **npm install**. 
 | |
|   There might be a few `npm WARN` messages along the way — and that is perfectly fine.
 | |
|   
 | |
|   We often see an `npm WARN` message after a series of `gyp ERR!` messages. 
 | |
|   Ignore them. A package may try to re-compile itself using `node-gyp`.
 | |
|   If the re-compile fails, the package recovers (typically with a pre-built version)
 | |
|   and everything works.
 | |
|   
 | |
|   Just make sure there are no `npm ERR!` messages at the very end of `npm install`.
 | |
|   
 | |
| .l-main-section
 | |
| :marked
 | |
|   <a id="ngmodule"></a>
 | |
|   ### Appendix: ***NgModule***
 | |
|   The `NgModule` decorator is listing:
 | |
| 
 | |
|   1. What other Angular Modules ours uses
 | |
|   1. Which components and directives we declare in our components
 | |
|   1. The component to bootstrap at the start 
 | |
| 
 | |
|   We import our lone `app.AppComponent` and add it to both `declarations` and `bootstrap` array.
 | |
| 
 | |
|   Notice that we also add `ng.platformBrowser.BrowserModule` to the `imports` array. 
 | |
|   This is the Angular Module that contains all the needed Angular bits and pieces to run our app in the browser.
 | |
| 
 | |
|   Angular itself is split into separate Angular Modules so we only need to import the ones we really use.
 | |
|   
 | |
|   One of the most common ones is `FormsModule`, and soon we'll also see `RouterModule` and `HttpModule`. 
 | |
| 
 | |
| .l-main-section
 | |
| :marked
 | |
|   <a id="main"></a>
 | |
|   ### Appendix: ***main.js***
 | |
| 
 | |
|   #### Bootstrapping is platform-specific
 | |
|   We use the `platformBrowserDynamic().bootstrapModule` function from `ng.platformBrowserDynamic`,
 | |
|   not `ng.core`. There's a good reason.
 | |
|   
 | |
|   We only call "core" those capabilities that are the same across all platform targets.
 | |
|   True, most Angular applications run only in a browser and we'll call the bootstrap function from
 | |
|   this library most of the time. It's pretty "core" if we're always writing for a browser.
 | |
|     
 | |
|   But it is possible to load a component in a different environment. 
 | |
|   We might load it on a mobile device with [Apache Cordova](https://cordova.apache.org/) or [NativeScript](https://www.nativescript.org/).
 | |
|   We might wish to render the first page of our application on the server 
 | |
|   to improve launch performance or facilitate 
 | |
|   [SEO](http://www.google.com/webmasters/docs/search-engine-optimization-starter-guide.pdf).
 | |
| 
 | |
|   These targets require a different kind of bootstrap function that we'd import from a different library.
 | |
|  
 | |
|   #### Why do we create a separate ***main.js***, ***app.module.js*** and ***app.component.js*** files?
 | |
|   
 | |
|   The *main.js* file is tiny. This is just a QuickStart.
 | |
|   We could have folded its few lines into the `app.module.js` file, and that one into
 | |
|   `app.component.js` and spared ourselves some complexity.
 | |
|   
 | |
|   We didn't for what we believe to be good reasons:
 | |
|   1. Doing it right is easy
 | |
|   1. Testability
 | |
|   1. Reusability
 | |
|   1. Separation of concerns
 | |
|   1. We learned about import and export
 | |
|   
 | |
|   #### It's easy
 | |
|   Sure it's an extra step and an extra file. How hard is that in the scheme of things?
 | |
|   
 | |
|   We'll see that a separate `main.js` and `app.module.js` is beneficial for *most* apps 
 | |
|   even if it isn't critical for the QuickStart.
 | |
|   Let's develop good habits now while the cost is low.
 | |
|   
 | |
|   #### Testability
 | |
|   We should be thinking about testability from the beginning
 | |
|   even if we know we'll never test the QuickStart. 
 | |
|   
 | |
|   It is difficult to unit test a component when there is a call to `bootstrapModule` in the same file.
 | |
|   As soon as we load the component file to test the component, 
 | |
|   the `bootstrapModule` function tries to load the application in the browser.
 | |
|   It throws an error because we're not expecting to run the entire application, 
 | |
|   just test the component. 
 | |
|   
 | |
|   Relocating the `bootstrapModule` function to `main.js` eliminates this spurious error
 | |
|   and leaves us with a clean component module file.
 | |
|   
 | |
|   #### Reusability
 | |
|   We refactor, rename, and relocate files as our application evolves.
 | |
|   We can't do any of those things while the file calls `bootstrapModule`.
 | |
|   we can't move it. 
 | |
|   We can't reuse the component in another application. 
 | |
|   We can't pre-render the component on the server for better performance.
 | |
|   
 | |
|   #### Separation of concerns
 | |
|   A component's responsibility is to present and manage a view, and a NgModule's
 | |
|   reponsibility is to define the application context.
 | |
|   
 | |
|   Launching the application has nothing to do with any of these.
 | |
|   That's a separate concern. The friction we're encountering in testing and reuse
 | |
|   stems from this unnecessary mix of responsibilities.
 | |
|   
 | |
|   #### Import/Export
 | |
|   
 | |
|   While writing a separate `main.js` and `app.module.js` files we learned an essential Angular skill:
 | |
|   how to 'export' from one 'module' and 'import' into another via our simple
 | |
|   namespace abstraction. 
 | |
|   We'll do a lot of that as we learn more Angular.
 |