Let's start out by creating a new folder called angular-2-components
in order to create our application:
npm init
npm install jspm --save-dev
jspm init
jspm install npm:@angular/core npm:@angular/common npm:@angular/compiler npm:@angular/platform-browser-dynamic npm:rxjs text
Let's examine what we've been creating so far by using the NPM and JSPM command-line tools.
The package.json
file is our Node.js configuration file that we're using as the base to work with JSPM (the package manager) and SystemJS (the module loader with transpiler). If you check out the package.json
file, you will see an additional section for JSPM dependencies:
"jspm": { "dependencies": { "@angular/common": "npm:@angular/[email protected]", "@angular/compiler": "npm:@angular/[email protected]", "@angular/core": "npm:@angular/[email protected]", "@angular/platform-browser-dynamic": "npm:@angular/[email protected]", "text": "github:SystemJS/[email protected]" }, "devDependencies": { "typescript": "npm:[email protected]", } }
Let's take a quick look at the dependencies we have installed using JSPM and their purpose:
Package |
Description |
---|---|
|
This is the core package of Angular 2, hosted on NPM. If you remember from Chapter 1, Component-Based User Interfaces, JSPM is only a broker, and it delegates to other package repositories. The core package contains all Angular-core modules, such as the |
|
The Angular |
|
The compiler package contains all the artifacts required to compile view templates. Angular not only provides the ability to precompile templates to gain faster booting time, but it also uses the compiler at runtime to convert text templates into compiled templates. This package is required if we're compiling templates at runtime. |
|
This package includes the bootstrapping functionality that will help us start our application. The bootstrap initiated by the platform-browser-dynamic package is dynamic in the sense of compiling templates at runtime. |
|
This development dependency is the TypeScript transpiler for SystemJS. It transpiles our ECMAScript 6 and TypeScript code to ECMAScript 5, from where it can run in the browser. |
|
This SystemJS loader supports the loading of text files in the form of JavaScript strings. This is especially useful if you like to load HTML templates and avoid asynchronous requests. |
Our main entry point for displaying our application within the browser is our index site. The index.html
file completes the following five actions:
config.js
file that contains the mapping information generated by JSPM.System.import
function to load and execute the main entry point, which is our boostrap.js
file.Let's create a new index.html
file within the root folder of our project:
<!doctype html> <html> <head lang="en"> <title>Angular 2 Components</title> </head> <body> <script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.35.0/es6-shim.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/2.0.0-beta.15/angular2-polyfills.js"></script> <script src="jspm_packages/system.js"></script> <script src="config.js"></script> <script> System.import('lib/bootstrap.js'); </script> </body> </html>
Let's move on to our application component. You can think of it as the outermost component of your application. It's the main component in that it represents your whole application. Every application needs one and just one main component. This is where your component tree has its roots.
We'll name our main component App
because it represents our whole application. Let's go ahead and create the component within a new lib
folder in our project folder. Create a file, app.js
, with the following content:
// We need the Component annotation as well as the // ViewEncapsulation enumeration import {Component, ViewEncapsulation} from '@angular/core'; // Using the text loader we can import our template import template from './app.html!text'; // This creates our main application component @Component({ // Tells Angular to look for an element <ngc-app> to create this // component selector: 'ngc-app', // Let's use the imported HTML template string template, // Tell Angular to ignore view encapsulation encapsulation: ViewEncapsulation.None }) export class App {}
There's nothing different here from what we already know about structuring a component, something that we learned in the previous chapter. However, there are two main differences here compared to how we created the components before. If you look at how we configured the template
property, you could tell that we didn't write the HTML template directly within the JavaScript file inside the ECMAScript 6 template strings. Instead, we're going to load the template into a JavaScript string using the text loader plugin in SystemJS. We can just load any text file from the file system by appending !text
to our regular ECMAScript 6 imports:
import template from './app.html!text';
This will load the file, app.html
, from the current directory and make a default export with its content as a string.
The second difference is that we're using ViewEncapsulation
to specify how Angular should handle view encapsulation. Angular has three ways, to handle view encapsulation, which provides different levels of granularity and has their own pros and cons. They are as follows:
Encapsulation type |
Description |
---|---|
|
If a component is set to emulated view encapsulation, it will emulate style encapsulation by attaching the generated attributes to the component element and modifying CSS selectors to include these attribute selectors. This will enable certain forms of encapsulation, although the outer styles can still leak into the component if there are other global styles. This view encapsulation mode is the default mode, if not specified otherwise. |
|
Native view encapsulation is supposed to be the ultimate goal of the view encapsulation concept within Angular. It makes use of Shadow DOM, as described in the previous chapter, to create an isolated DOM for the whole component. This mode depends on the browser to support Shadow DOM natively, and therefore, can't always be used. It's also important to note that global styles will no longer be respected and local styles need to be placed within the component in inline style tags (or use the |
|
This mode tells Angular not to provide any template or style encapsulation. Within our application, we mainly rely on styles coming from a global CSS; therefore, we use this mode for most of the components. Neither Shadow DOM, nor attributes will be used to create style encapsulation; we can simply use the classes specified within our global CSS file. |
As this component is now relying on a template to be loaded from the file system, we need to create the app.html
file in the lib
folder with some initial content:
<div>Hello World!</div>
For the time being, that's everything we put in our template. Our directory should look similar to this:
angular-2-components ├── node_modules/ ├── jspm_packages/ ├── config.js ├── index.html ├── lib │ ├── app.html │ └── app.js └── package.json
Now that we have created our main application component, we can add the component's host element to our index.html
file:
<!DOCTYPE html>
<html>
<head lang="en">
<title>Angular 2 Components</title>
</head>
<body>
<ngc-app></ngc-app>
...
The index.html
file will load the bootstrap.js
module using SystemJS in an inline script
tag. It's a best practice to have a main entry point for your scripts when working with SystemJS. Our bootstrap.js
file is responsible for loading all the necessary JavaScript dependencies for our application as well as bootstrapping the Angular framework.
We can go ahead and bootstrap our Angular application by providing our main application component, App
. We need to import the bootstrap
function from the angular2
module. We can then import our App
component and call the bootstrap
function, passing it as parameter:
// Import Angular bootstrap function import {bootstrap} from '@angular/platform-browser-dynamic'; // Import our main app component import {App} from './app'; // We are bootstrapping Angular using our main application // component bootstrap(App);
The code we've produced so far should now be in a state where we can run it. Before we run our code using the live-server module, let's ensure we have all the files ready. At this stage, our directory should look something like this:
angular-2-components ├── jspm_packages/ ├── node_modules/ ├── config.js ├── index.html ├── lib │ ├── app.html │ ├── app.js │ └── bootstrap.js └── package.json
Now let's start live server to start a server and a browser with live reload. For this, we need to simply execute the following command on the command line within our project folder:
live-server
If everything goes well, you will have an open web browser that shows Hello World!.
Let's recap what we have done so far:
app.js
.bootstrap.js
script to include the Angular framework boot of our application.index.html
file by including an element that matches our component selector property.