angular2初入眼帘之-搭个环境

angular2是什么?我猜不容我赘述,各位一定略有耳闻,无论是曾经AngularJS的拥趸,亦或是React的粉丝,都或多或少的对她有过一点了解。未见其物、先闻其声,angular2在问世之前已经做足了宣传,想必诸位也一定被下面各种词汇所震慑,什么:TypeScriptES5ES6DartImmutableUnidirectional Data FlowReactive ProgrammingDecoratorsSystem.jswebpack...,天花乱坠,美不胜收!但我们不禁要问,“都说AngularJS学习曲线陡峭,也没陡出这些个莫名词汇!”,angular2究竟该如何上手?看了这些个知识点,有木有吓得手抖,都搞不清从何处入手了!?

本教程主旨:多些操作、少点说教(理论是进阶必须的,千万不要误读),让我们从实践中追寻真理吧!

本章源码:environment

本章使用angular2版本为:2.0.0-rc.1

# 推荐开发工具

# Atom

这里我推荐使用Atom,以及她的TypeScript插件atom-typescript。很爽的哦!

# 创建项目

mkdir environment
cd environment
npm init

根据npm init提问,创建package.json文件,创建后去掉不必要的字段,像这样即可:

{
  "name": "environment",
  "version": "1.0.0",
  "description": "I will show you how to set up angular2 development environment",
  "keywords": [
    "angular2",
    "environment"
  ],
  "author": "Howard.Zuo",
  "license": "MIT"
}

# 安装运行时依赖

npm install --save --save-exact @angular/common@2.0.0-rc.1 @angular/core@2.0.0-rc.1 @angular/compiler@2.0.0-rc.1 @angular/platform-browser@2.0.0-rc.1 @angular/platform-browser-dynamic@2.0.0-rc.1 es6-shim reflect-metadata rxjs@5.0.0-beta.6 zone.js
  • @angular: 这个必须的,没意见吧?之所以分了多个包,这是最新2.0.0-rc.1的变化,可以按需引入,增加灵活性
  • es6-shim: angular2依赖了大量ES2015的特性,这可能导致一些不支持ES2015特性的浏览器无法运行angular2程序(例如:老版本IE)。所以需要该shim来保证老浏览器的正确性
  • reflect-metadata: angular2允许开发者使用Decorator,这使得程序具备更好的可读性。无奈DecoratorES2016里的提案,需要reflect-metadata提供反射API才能使用
  • rxjs: 一个Reactive ProgrammingJavaScript实现。这里对她的依赖是因为angular2支持多种数据更新模式,比如:fluxRx.js
  • zone.js: 用来对异步任务提供Hooks支持,使得在异步任务运行之前/之后做额外操作成为可能。在angular2里的主要应用场景是提高脏检查效率、降低性能损耗。

# 安装开发环境依赖

npm install --save-dev webpack ts-loader typescript lite-server concurrently tsd
  • webpack: 我们这里使用webpack对源码进行编译、打包,而不是用官网介绍的System.js的运行时加载、解释、执行。合并打包的好处不用我多说吧?减少请求数、uglify、预检查...
  • ts-loader: TypeStrong出品的TypeScript加载器,通过该加载器,TypeScript源码可以顺利被编译成ES5代码
  • typescript: angular2官方推荐的开发语言,我们在教程里也将使用该语言进行代码编写
  • lite-server: 一个轻量级的静态服务器,本章节我们就用它启动程序
  • concurrently: 这是一个可以让多个阻塞命令同时执行、管理的工具。我们将在后面用到
  • tsd: typescript定义文件管理系统,由于angular2依赖ES2015的诸多特性,譬如:Promise等,所以需要这些API的支持以及typescript定义

# 第一个示例

# 创建index.html

touch index.html

向刚才创建的index.html里添加如下内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>environment</title>
</head>
<body>
    <!--这里引用我们的第一个component-->
    <my-app></my-app>
    <!--加载使用webpack编译后的bundle-->
    <script type="text/javascript" src="/dist/bundle.js"></script>
</body>
</html>

# 创建app.ts

mkdir ts
touch ts/app.ts

向刚才创建的ts/app.ts里添加如下内容:

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

//声明第一个component
@Component({
    selector: 'my-app',
    template: '<h1>My First Angular 2 App</h1>'
})
export class AppComponent { }

# 创建index.ts

touch ts/index.ts

向刚才创建的ts/index.ts里添加如下内容:

import 'es6-shim';
import 'reflect-metadata';
import 'zone.js/dist/zone';
import {bootstrap} from '@angular/platform-browser-dynamic';

import {AppComponent} from './app';

//启动程序
bootstrap(AppComponent);

# 创建webpack.config.js

touch webpack.config.js

向刚才创建的webpack.config.js里添加如下内容:

'use strict';

var path = require('path');

module.exports = {
    entry: {
        index: './ts/index.ts'
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js',
        publicPath: 'dist/'
    },
    module: {
        loaders: [
            {
                test: /\.ts$/,
                loader: 'ts'
            }
        ]
    },
    resolve: {
        extensions: [
            '',
            '.js',
            '.ts'
        ]
    }
};

# 创建tsconfig.json

touch tsconfig.json

向刚才创建的tsconfig.json里添加如下内容:

{
    "compilerOptions": {
        "noImplicitAny": true,
        "removeComments": true,
        "module": "commonjs",
        "target": "es5",
        "moduleResolution": "node",
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "sourceMap": true,
        "declaration": false
    },
    "buildOnSave": false,
    "compileOnSave": false,
    "exclude": [
        "node_modules"
    ],
    "atom": {
        "rewriteTsconfig": true,
        "formatOnSave": true
    }
}

# 创建tsd.json

touch tsd.json

向刚才创建的tsd.json里添加如下内容:

{
  "version": "v4",
  "repo": "DefinitelyTyped/DefinitelyTyped",
  "ref": "master",
  "path": "typings",
  "bundle": "typings/tsd.d.ts",
  "installed": {
    "es6-promise/es6-promise.d.ts": {
      "commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
    },
    "es6-collections/es6-collections.d.ts": {
      "commit": "6eebd5e90a1cbd6b47b0705ba72dbcd5baf846f3"
    }
  }
}

#package.json增加常用命令

package.json中,增加scripts属性,内容如下:

"scripts": {
  "preinstall": "tsd install",
  "watch": "webpack -w",
  "start": "concurrently \"npm run watch\" \"lite-server\""
}
  • preinstall: 执行npm install之前自动执行该脚本,将ES2015的定义文件下载下来
  • watch: 使用npm run watch调用。编译、打包源码,并持续监视源码变动,一旦你做了改动,自动重新编译、打包
  • start: 使用npm start调用。这里用到了之前提到的concurrently包,她使的一条命令可以同时执行两个阻塞操作npm run watch以及lite-server

# 运行

好了,到目前为止,我们第一个示例的开发/运行环境就基本搭好了,现在启动试试看:

npm start

你会看到:

angular

下回预告:牛刀小试component