Angular released version 4.0.0 last month, so get up to speed. This article guides you through building a simple Angular application that explains each point in as much detail as possible.

First of all, I chose webpack2 as a packaging tool. The reason for wenpack2 is self-evident. Assuming you already know some of the basics of Webpack2, let’s get started

See my Git project for detailed code

1. Configure WebPack

Start by creating a new project folder

mkdir angular-dream
cd angular-dreamCopy the code

Create a package.json file by entering the command NPM init in the console. As shown in figure:

Create a package.json file



angular-dream

Once created, open the project in the editor (I used WebStorm).

Configuration of package.json files

For the meaning of some parameters in package.json file, please refer to this article written by Teacher Ruan Yifeng.

{
  "name": "angular2-dream"."version": "1.0.0"."description": "Hello Angular2"."scripts": {
    "start": "webpack-dev-server --config config/webpack.dev.js --progress"."test": "karma start"."build": "webpack --config config/webpack.dev.js --progress --profile --bail"."webpack": "webpack"."rimraf": "rimraf"
  },
  "keywords": [
    "angular2"."webpack"]."author": "[email protected]"."license": "MIT"."dependencies": {
    "@angular/animations": "~ 4.0.1"."@angular/common": "~ 4.0.0"."@angular/compiler": "~ 4.0.0"."@angular/core": "^ 4.0.1." "."@angular/forms": "~ 4.0.1"."@angular/http": "~ 4.0.1"."core-js": "^ against 2.4.1." "."rxjs": "5.2.0"."zone.js": "^ 0.8.5"
  },
  "devDependencies": {
    "reflect-metadata": "^ 0.1.10"."html-webpack-plugin": "^ 2.28.0"."@angular/compiler-cli": "~ 4.0.1"."@angular/platform-browser": "~ 4.0.1"."@angular/platform-browser-dynamic": "~ 4.0.1"."@angular/platform-server": "~ 4.0.1"."@angular/router": "~ 4.0.1"."@angularclass/hmr": "^ 1.2.2." "."@angularclass/hmr-loader": "^ 3.0.2." "."@types/jasmine": "^ 2.5.43"."@types/node": "^ 6.0.45"."angular2-template-loader": "^ 0.6.0"."awesome-typescript-loader": "^ 3.0.4"."bootstrap": 6 "" ^ 4.0.0 - alpha.."bootstrap-sass": "^ 3.3.7." "."css-loader": "^ 0.26.1"."extract-text-webpack-plugin": 5 "" 2.0.0 - beta.."file-loader": "^ 0.9.0"."font-awesome": "^ 4.7.0"."html-loader": "^ 0.4.3." "."postcss-loader": "^ 1.3.1." "."raw-loader": "^ 0.5.1"."style-loader": "^ 0.13.1." "."to-string-loader": "^ 1.1.5." "."ts-helpers": "^ 1.1.2." "."url-loader": "^ 0.5.7"."webpack": "2.2.0"."webpack-dev-server": "2.2.0 - rc. 0"."webpack-merge": "^ 2.4.0." "."typescript": "^ 2.2.2." "}}Copy the code
  • @angular/compiler– Angular template compiler. It understands templates and converts them into code that applications can run and render. Developers typically do not deal with this compiler directly, but use it indirectly through platform-browser-Dynamic or offline template compilers.
  • @angular/platform-browser– Everything related to the DOM and the browser, especially the part that helps render into the DOM. The package also contains the bootstrapStatic method for bootstrapping applications that require precompiled templates offline at production build time
  • @angular/platform-browser-dynamic– Provide providers and bootstrap methods for the application to compile templates on the client side. Do not use it for offline compilation. We use this package to bootstrap the application during development, as well as the example in Plunker.
  • core-js– Patch for Global Context (Window), which provides many basic ES2015(ES6) features. We can also replace it with another populated library that provides the same kernel API. Once all “major browsers” implement these apis, this dependency can be removed.
  • reflect-metadata– A dependency package shared by Angular and TypeScript compilers.

Tsconfig. json file configuration

Create the tsconfig.json file in the root directory of your project.

Browsers can’t execute TypeScript directly; they need to use a compiler to translate it into JavaScript, and the compiler does some configuration. The configuration of tsconfig.json instructs the compiler how to generate JavaScript files.

{
  "compilerOptions": {
    "declaration": false."module": "commonjs".// How to organize code
    "target": "es5".// Compile the target platform
    "moduleResolution": "node"."sourceMap": true.// Whether to generate the corresponding SourceMap file when mutating ts file to js file
    "emitDecoratorMetadata": true.// Let TypeScript support generate metadata for declarations with decorators
    "experimentalDecorators": true.// Whether to enable the experimental decorator feature
    "noImplicitAny": true."lib": ["dom"."es6"]."suppressImplicitAnyIndexErrors": true
  },
  "exclude": [
    "node_modules"."dist"]."awesomeTypescriptLoaderOptions": {
    "forkChecker": true."useWebpackText": true
  },
  "compileOnSave": false."buildOnSave": false
}Copy the code

When the noImplicitAny flag is true and the TypeScript compiler cannot infer the type, it still generates JavaScript files. But it also reports an error. Many experienced programmers prefer this strict setting because type checking catches more unexpected errors at compile time.

Create the webpack.config.js file

Create the webpack.config.js file in the root directory

module.exports = require('./config/webpack.dev.js');Copy the code

Now run the NPM install command in the console to install the project’s dependencies.

Second, the Polyfills

After configuring the above files, we create a SRC folder in the root directory of the project.

Create a new polyfills. Ts file under the SRC folder.

The polyfills. Ts file introduces standard JS for running Angular applications.

import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/set';
import 'core-js/es6/weak-map';
import 'core-js/es6/weak-set';
import 'core-js/es6/typed';

/** Evergreen browsers require these. **/
import 'core-js/es6/reflect';

import 'core-js/es7/reflect';

/*************************************************************************************************** * Zone JS is required by Angular itself. */
import 'zone.js/dist/zone';

import 'ts-helpers';

if (process.env.ENV === 'production') {
  // Production
} else {
  // Development and test
  Error['stackTraceLimit'] = Infinity;
  require('zone.js/dist/long-stack-trace-zone');
}Copy the code

Third, Vendor

Create a new vendor.ts file under the SRC folder.

The vendor.ts file introduces some third-party dependencies.

// Angular
// Contains all provider dependencies
import '@angular/platform-browser';
import '@angular/platform-browser-dynamic';
import '@angular/compiler';
import '@angular/core';  // Store core code, such as change monitoring mechanism, dependency injection mechanism, rendering, decorator, etc.
import '@angular/common';
import '@angular/http';
import '@angular/router';

// RxJS
import 'rxjs/Observable';
import 'rxjs/Subscription';
import 'rxjs/Subject';
import 'rxjs/BehaviorSubject';

// Bootsctrap
import 'bootstrap/dist/css/bootstrap.css';
import 'font-awesome/css/font-awesome.css';Copy the code

Four, the Main

Create a new main.ts file under the SRC folder.

In the main.ts file, we specify the root module of the project as AppModule

import {AppModule} from './app/app.module';
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";

platformBrowserDynamic().bootstrapModule(AppModule);

// platformBrowserDynamic().bootstrapModule() to compile and enable the AppModule module
// Initialize a runtime environment based on the current runtime environment, such as operating system, browser, and then run the AppModule from this environment.Copy the code

Five, the config

Create a config folder under the root directory

helpers.js

Create helpers.js under the config folder.

Note the order of entries polyfills,vendor, and app.

var path = require('path');
var _root = path.resolve(__dirname, '.. ');
function root(args) {
  args = Array.prototype.slice.call(arguments.0);
  return path.join.apply(path, [_root].concat(args));
}
exports.root = root;Copy the code

webpack.common.js

Create a webpack.common.js file under the config folder.

const helpers = require('./helpers');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    'polyfills': './src/polyfills.ts'.// Standard JS required to run Angular
    'vendor': './src/vendor.ts'.// Angular, Lodash, bootstrap. CSS......
    'app': './src/main.ts' // Application code
  },
  resolve: { // The configuration when resolving the module path
    extensions: ['.ts'.'.js'] // Specify the suffix of the module, which will be automatically completed when the module is introduced
  },
  module: {
    rules: [ // Tell Webpack what loader to use for each type of file
      {
        test   : /\.ts$/.loaders: ['awesome-typescript-loader'.'angular2-template-loader']
        //awesome-typescript-loader - a loader for translating typescript code into ES5, which is guided by the tsconfig.json file
        // Angular2-template-loader - Used to load Angular component templates and styles
      }, {
        test: /\.json$/.use : 'json-loader'
      }, {
        test: /\.styl$/.loader: 'css-loader! stylus-loader'
      }, {
        test   : /\.css$/.loaders: ['to-string-loader'.'css-loader'] {},test: /\.html$/.use: 'raw-loader'.exclude: [helpers.root('src/index.html')]
        // HTML - The loader for the component template
      }, {
        test:/\.(jpg|png|gif)$/.use:"file-loader"
      }, {
        test: /\.woff(2)? (\? v=[0-9]\.[0-9]\.[0-9])? $/.use : "url-loader? limit=10000&minetype=application/font-woff"
      }, {
        test: /\.(ttf|eot|svg)(\? v=[0-9]\.[0-9]\.[0-9])? $/.use : "file-loader"}},plugins: [
    / / hot replacement
    new webpack.HotModuleReplacementPlugin(),
    new webpack.optimize.CommonsChunkPlugin({
      name: ['vendor'.'polyfills']
      // Multiple HTML files share one JS file to extract common code
    }),

    new HtmlWebpackPlugin({
      template: './src/index.html'
      // Automatically injects script and link tags into target.html files}})];Copy the code

webpack.dev.js

Create a webpack.dev.js file under the config folder.

var webpackMerge = require('webpack-merge');
var commonConfig = require('./webpack.common.js');
const helpers = require('./helpers');

module.exports = webpackMerge(commonConfig, {
  output   : {
    path      : helpers.root('dist'),
    publicPath: '/'.filename  : '[name].js'
  },
  devServer: {
    port              : 8080.historyApiFallback: true}});Copy the code

So far, the directory structure now looks like the following:



AppModule
main.ts

6. Root AppModule

Now that the basic configuration is complete, let’s create the root module

Create a new app folder under the SRC file,

Create app.com ponent. Ts

Create a new app.component.ts file under the app folder

import { Component } from "@angular/core";

@Component({
  selector   : 'root-app'.templateUrl: './app.component.html'
})
export class AppComponent {
  constructor() {}}Copy the code

Create app.com ponent. HTML

Create a new app.component.html file under the app folder

<h1 class="title">Hello Angular2</h1>

<router-outlet></router-outlet>Copy the code

To create the app. Routes. Ts

Here we use a route to complete the jump between pages

import { Routes } from '@angular/router';
import { AppComponent } from "./app.component";
export const routes: Routes = [ // Routes an array of types
  {
    path      : 'index'.component : AppComponent
  },{
    path      : ' '.redirectTo: 'index'.pathMatch : 'full'}];Copy the code

To create the app. The module. Ts

Create a new app.module.ts file under the app folder

import { AppComponent } from './app.component';
import { routes } from './app.routes';
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";
import { RouterModule } from "@angular/router";
import { NgModule } from "@angular/core";
//@NgModule decorator is used to define metadata for modules
@NgModule({ // @ngModule is used to define decorators for modules
  declarations: [AppComponent], // Import components, directives, etc. that the module depends on to specify the module's view class
  imports: [
    BrowserModule, // Contains commonModule and applicationModule modules, which encapsulate some of the browser runtime libraries
    FormsModule,  // Form-related component directives, etc., including [(ngModel)]
    RouterModule.forRoot(routes,{useHash: false}), // RouterModule.forroot () to create the root routing module].// Import additional modules required by the current module
  bootstrap: [AppComponent], // Marks the boot component
  // Mark the AppComponent as a bootstrap component. When Angular bootstrap the application, it renders in the DOM
  // Dye the AppComponent and place the result inside the element in index.html.
})
export class AppModule {}Copy the code

Host page

Create a new index.html file under the SRC folder


      
<html>
<head>
    <meta charset="utf-8">
    <title>Angular2 Hello Word</title>
    <base href="/">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <root-app>Loading...</root-app>
</body>
</html>Copy the code

Now, the project directory structure looks like the following:

Start your Angular journey by running NPM start

Reference:

  • Angular Official website