使用typescript和gulp快速开始Angular 2开发
Angular2出来了一段时间,通过更简单和更简洁的概念,如基于组件的架构,新的依赖注入或内置模块化,新版本的框架要学习得简单得多。在这个分步教程中,您将了解如何使用TypeScript和Gulp开始使用Angular2。源代码在Github上可用。
本文是翻译codeleak.pl上的一篇文章。(英语很挫,错误在所难免)
原文地址:
通用说明
更新日志
15/09/2016升级到2.0.0重新angular2文章,添加新的代码库中的代码来反映。添加快速入门指南。
06/09/2016 - 更新至 Angular2 to 2.0.0-rc.6
05/06/2016 - typings updated to 1.0.4. Section related to that part changed too.
05/05/2016 - Upgraded Angular2 to 2.0.0-rc.1
22/04/2016 - Upgraded Angular2 to 2.0.0-beta.15
26/03/2016 - Upgraded Angular2 to 2.0.0-beta.12
21/03/2016 - Upgraded Angular2 to 2.0.0-beta.11 (the post itself as well as the source code)
快速入门
如果你不感兴趣的一步一步的教程,只需按照以下步骤迅速启动。
1、环境要求
Nodejs 必须安装在您的系统和下面的全局节点包必须安装:
gulpnpm i -g gulpgulp-clinpm i -g gulp-clitypingsnpm i -g typings@1.3.3typescriptnpm i -g typescript@2.0.2ts-nodenpm i -g ts-node@1.3.0
2、克隆仓库
git clone https://github.com/kolorobot/angular2-typescript-gulp.git
3、定位至angular2-typescript-gulp目录
cd angular2-typescript-gulp
4、安装依赖
npm install
5、构建工程
npm run clean & npm run build// 构建后会产生Build目录
6、启动应用
npm start
介绍
至今,Angular 1.X可能仍然是最流行的前端框架,毫无疑问Angular 1.X是一个伟大的框架。然而,这是非常难以掌握。复杂的API和许多概念推出以来,使人了解框架和有效地使用它确实很难。
angular2,另一方面,是一个新的开放。新版本的框架要简单得多,学习更简单和更简洁的概念,如基于组件的体系结构,新的依赖注入或内置模块化。
如果你想找一个比更好地 练习和开始学习Angular 2的地方,如果正在寻找用gulp构建来使用Angular 2的方式,那么这篇文档正适合你!
Note: 文章所使用的代码资源在github
工程预览
初始化的工程是基于Angular2 Quickstart:
对 做了一些改变。最重要的变化是将源文件与生成文件分离:SRC目录包含所有源文件并生成包含所有已编译和处理的文件。服务器使用build目录作为基本目录来资源文件。angular2-typescript-gulp| .gitignore| bs-config.json -> BrowserSync configuration| gulpfile.ts -> Gulp in TypeScript| package.json -> npm configuration| tsconfig.json -> TypeScript configuration| typings.json -> TypeScript typings definitions| tslint.json -> tslint configuration|\---src│ │ index.html -> Starting point for the application│ │ systemjs.config.js -> SystemJS configuration│ ││ \---app -> Application modules│ │ app.component.ts -> Main application component│ │ app.html -> Main application template │ │ app.module.ts -> Application module definition │ │ app.routing.ts -> Routing configuration │ │ main.ts -> Application bootstrap │ ││ \---about │ │ └───components│ │ about.components.ts│ │ about.html│ ││ \---todo│ ├───components│ │ task-list.component.ts│ │ task-list.css│ │ task-list.html│ │ task.component.ts│ │ task.html│ ││ \---models│ │ task.ts│ ││ \---services│ task-service.ts
NPM全局依赖
假设Node和NPM已经安装,你可以通过调用下面的命令安装全局依赖:
npm i -g
为了运行工程必须安装的全局依赖:
gulp and gulp-clinpm i -g gulp npm i -g gulp-clitypingsnpm i -g typings@1.3.3typescriptnpm i -g typescript@2.0.2ts-nodenpm i -g ts-node@1.3.0// Note: To check global dependencies use the following command:npm -g –depth 0 ls
创建工程目录和文件
创建如上文所述的目录和文件结构
构建配置
1、typescript配置 - tsconfig.ts
编译文件会被保存至build/app;请注意gulpfile.ts要排除编译。
{ "compilerOptions": { "outDir": "build/app", "target": "es5", "module": "system", "moduleResolution": "node", "sourceMap": true, "emitDecoratorMetadata": true, "experimentalDecorators": true, "removeComments": false, "noImplicitAny": false }, "exclude": [ "gulpfile.ts", "node_modules" ]}
说明:如果你想导入你的工程到IDE(如IntelliJ),让这个IDE也使用这个文件。
2、Typings - typings.json
To get started we need some definitions to be installed. Run the following commands:
为了能够正常运行开始,我们需要的一些定义被安装。运行一下命令:typings install –global –save dt~core-js typings install –global –save dt~node
这些会被添加至typings.json
{ "globalDependencies": { "core-js": "registry:dt/core-js#0.0.0+20160725163759", "node": "registry:dt/node#6.0.0+20160909174046", }}
Typings will be download to typings directory and they will be downloaded on npm install.
Typings 会被下载到typings目录并且他们会通过npm instal的方式被下载下来。
3、npm包和脚本配置 - package.json
关于脚本命令的一些命令:
clean - 清除build目录
compile - TypeScript compilation (with sourcemaps)
build - 打包构建工程
start - 运行使用来自bs-config.json配置的lite服务器,它还使用监视任务同步源目录的任何更改
{ "name": "angular2-typescript-gulp", "version": "1.0.0", "description": "Angular2 with TypeScript and Gulp QuickStart", "scripts": { "clean": "gulp clean", "compile": "gulp compile", "build": "gulp build", "start": "concurrent --kill-others \"gulp watch\" \"lite-server\"", "postinstall": "typings install" }, "repository": { "type": "git", "url": "https://github.com/kolorobot/angular2-typescript-gulp.git" }, "author": "Rafał Borowiec", "license": "MIT", "bugs": { "url": "https://github.com/kolorobot/angular2-typescript-gulp/issues" }, "dependencies": { "@angular/common": "2.0.0", "@angular/compiler": "2.0.0", "@angular/core": "2.0.0", "@angular/forms": "2.0.0", "@angular/http": "2.0.0", "@angular/platform-browser": "2.0.0", "@angular/platform-browser-dynamic": "2.0.0", "@angular/router": "3.0.0", "@angular/upgrade": "2.0.0", "core-js": "^2.4.1", "reflect-metadata": "^0.1.3", "rxjs": "5.0.0-beta.12", "systemjs": "0.19.27", "zone.js": "^0.6.23" }, "devDependencies": { "concurrently": "^2.2.0", "del": "^2.2.0", "gulp": "^3.9.1", "gulp-sourcemaps": "^1.6.0", "gulp-tslint": "^6.1.1 ", "gulp-typescript": "^2.13.6", "lite-server": "^2.2.2", "tslint": "^3.5.0", "typescript": "^2.0.2", "typings": "^1.3.3", "ts-node": "^1.3.0" }}
4、BrowserSync configuration - lite-server
默认情况下,内容从当前目录提供,因此需要更改;而且,由于Lite Server使用BrowserSync,足以提供配置服务器的bs-config.json来从构建目录提供内容。
{ "port": 8000, "files": [ "build/**/*.{html,htm,css,js}" ], "server": { "baseDir": "build" }}
5、tslint(typescript语法检测配置) - tslint.json
TSLint检查TypeScript代码是否可读性,可维护性和功能错误,而Gulp可以与gulp-tslint插件一起使用。
tslint.json用于配置哪些规则可以运行。只需将文件添加到项目的根目录。您应该根据需要调整规则。您可以在这里找到有关规则的更多信息:
{ "rules": { "class-name": true, "curly": true, "eofline": false, "forin": true, "indent": [ true, 4 ], "label-position": true, "label-undefined": true, "max-line-length": [ true, 140 ], "no-arg": true, "no-bitwise": true, "no-console": [ true, "debug", "info", "time", "timeEnd", "trace" ], "no-construct": true, "no-debugger": true, "no-duplicate-key": true, "no-duplicate-variable": true, "no-empty": false, "no-eval": true, "no-string-literal": false, "no-trailing-whitespace": true, "no-unused-variable": false, "no-unreachable": true, "no-use-before-declare": true, "one-line": [ true, "check-open-brace", "check-catch", "check-else", "check-whitespace" ], "radix": true, "semicolon": true, "triple-equals": [ true, "allow-null-check" ], "variable-name": false, "whitespace": [ true, "check-branch", "check-decl", "check-operator", "check-separator" ] }}
6、Gul构建配置- gulpfile.ts
要开始,我们需要一个编译TypeScript文件,将资产和依赖关系复制到构建目录的任务。为了实现这些任务需要几个任务。
注意:Gulp文件是以TypeScript而不是JavaScript创建的。它需要ts-node执行,如本教程开头所述。
"use strict";const gulp = require("gulp");const del = require("del");const tsc = require("gulp-typescript");const sourcemaps = require('gulp-sourcemaps');const tsProject = tsc.createProject("tsconfig.json");const tslint = require('gulp-tslint');/** * Remove build directory. */gulp.task('clean', (cb) => { return del(["build"], cb);});/** * Lint all custom TypeScript files. */gulp.task('tslint', () => { return gulp.src("src/**/*.ts") .pipe(tslint({ formatter: 'prose' })) .pipe(tslint.report());});/** * Compile TypeScript sources and create sourcemaps in build directory. */gulp.task("compile", ["tslint"], () => { let tsResult = gulp.src("src/**/*.ts") .pipe(sourcemaps.init()) .pipe(tsc(tsProject)); return tsResult.js .pipe(sourcemaps.write(".", {sourceRoot: '/src'})) .pipe(gulp.dest("build"));});/** * Copy all resources that are not TypeScript files into build directory. */gulp.task("resources", () => { return gulp.src(["src/**/*", "!**/*.ts"]) .pipe(gulp.dest("build"));});/** * Copy all required libraries into build directory. */gulp.task("libs", () => { return gulp.src([ 'core-js/client/shim.min.js', 'systemjs/dist/system-polyfills.js', 'systemjs/dist/system.src.js', 'reflect-metadata/Reflect.js', 'rxjs/**', 'zone.js/dist/**', '@angular/**' ], {cwd: "node_modules/**"}) /* Glob required here. */ .pipe(gulp.dest("build/lib"));});/** * Watch for changes in TypeScript, HTML and CSS files. */gulp.task('watch', function () { gulp.watch(["src/**/*.ts"], ['compile']).on('change', function (e) { console.log('TypeScript file ' + e.path + ' has been changed. Compiling.'); }); gulp.watch(["src/**/*.html", "src/**/*.css"], ['resources']).on('change', function (e) { console.log('Resource file ' + e.path + ' has been changed. Updating.'); });});/** * Build the project. */gulp.task("build", ['compile', 'resources', 'libs'], () => { console.log("Building the project ...");});
7、安装依赖关系并检查构建
现在是安装所有依赖关系的时候了。运行:
npm install
应该在安装期间创建node_modules和typing目录。
构建工程
npm run clean & npm run build
build目录应在构建期间创建
注意:如果在编译期间看到以下内容,请确保至少有ts-node 1.3.0:
[00:49:42] Failed to load external module ts-node/register[00:49:42] Failed to load external module typescript-node/register[00:49:42] Failed to load external module typescript-register[00:49:42] Failed to load external module typescript-require
工程配置
1. Index - src/index.html
库是在构建任务期间创建的lib目录的引用
Angular 2 TypeScript Gulp QuickStart Loading...
2. SystemJS 配置 - src/systemjs.config.js
function (global) { System.config({ paths: { // paths serve as alias 'npm:': 'lib/' }, // map tells the System loader where to look for things map: { // our app is within the app folder app: 'app', // angular bundles '@angular/core': 'npm:@angular/core/bundles/core.umd.js', '@angular/common': 'npm:@angular/common/bundles/common.umd.js', '@angular/compiler': 'npm:@angular/compiler/bundles/compiler.umd.js', '@angular/platform-browser': 'npm:@angular/platform-browser/bundles/platform-browser.umd.js', '@angular/platform-browser-dynamic': 'npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js', '@angular/http': 'npm:@angular/http/bundles/http.umd.js', '@angular/router': 'npm:@angular/router/bundles/router.umd.js', '@angular/forms': 'npm:@angular/forms/bundles/forms.umd.js', // other libraries 'rxjs': 'npm:rxjs' }, // packages tells the System loader how to load when no filename and/or no extension packages: { app: { main: './main.js', defaultExtension: 'js' }, rxjs: { defaultExtension: 'js' } } });})(this);
3、应用组件
1. 主入口组件 - src/app/app.component.ts
import {Component, OnInit} from "@angular/core";@Component({ selector: "app", templateUrl: "./app/app.html"})export class AppComponent implements OnInit { ngOnInit() { console.log("Application component initialized ..."); }}
他的模板 (src/app/app.html):
Angular 2 is running ...
2. About 模块
关于模块由两个基本构件 - 组件及其模板组成。
src/app/about/components/about.component.ts
import {Component} from "@angular/core";import {OnInit} from "@angular/core";@Component({ templateUrl: './app/about/components/about.html'})export class AboutComponent implements OnInit { ngOnInit() { }}
src/app/about/components/about.html:
About
这是about
3. Todo 模块
Todo模块有点复杂 - 它包含组件,模型和服务。
src/app/todo/components/task.component.ts
import {Component} from "@angular/core";import {Input} from "@angular/core";import {Task} from "../models/task";import {Output} from "@angular/core";import {EventEmitter} from "@angular/core";@Component({ selector: 'task', templateUrl: './app/todo/components/task.html'})export class TaskComponent { @Input() task:Task; @Output() statusChanged:any = new EventEmitter(); toggleDone() { this.task.toggleDone(); this.statusChanged.emit(null); }}
src/app/todo/components/task.html
src/app/todo/components/task-list.component.ts
import {Component} from "@angular/core";import {Task} from "../models/task";import {OnInit} from "@angular/core";import {TaskService} from "../services/task-service";import {TaskComponent} from "./task.component";@Component({ selector: 'task-list', templateUrl: './app/todo/components/task-list.html', styleUrls: ['./app/todo/components/task-list.css'], providers: [TaskService]})export class TaskListComponent implements OnInit { todoCount:number; selectedTask:Task; tasks:Array; constructor(private _taskService:TaskService) { this.tasks = _taskService.getTasks(); this.calculateTodoCount(); } ngOnInit() { console.log("Todo component initialized with " + this.tasks.length + " tasks."); } calculateTodoCount() { this.todoCount = this.tasks.filter(t => !t.done).length; } select(task:Task) { this.selectedTask = task; }}
src/app/todo/components/task-list.css
li.selected { background-color: #8a8a8a;}
src/app/todo/components/task-list.html
Todo tasks ({ {todoCount}})
src/app/todo/models/task.ts
export class Task { constructor(public name:string, public done:boolean) { } toggleDone() { this.done = !this.done; }}
src/app/todo/services/task-service.ts
import {Injectable} from "@angular/core";import {Task} from "../models/task";@Injectable()export class TaskService { private tasks:Array= [ new Task("Task 1", false), new Task("Task 2", false), new Task("Task 3", false), new Task("Task 4", false), new Task("Task 5", false) ]; getTasks():Array { return this.tasks; } addTask(name:string) { this.tasks.push(new Task(name, false)); }}
4. Angular2 路由 - src/app/app.routing.ts
import {Routes, RouterModule} from '@angular/router';import {TaskListComponent} from "./todo/components/task-list.component";import {AboutComponent} from "./about/components/about.component";import {ModuleWithProviders} from "@angular/core";const appRoutes: Routes = [ {path: 'tasks', component: TaskListComponent, data: {title: 'TaskList'}}, {path: 'about', component: AboutComponent, data: {title: 'About'}}];export const appRoutingProviders: any[] = [];export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes, { useHash: true });
5. 模块定义 - src/app/app.module.ts
Angular2模块有助于将应用程序整合到一个功能性的集合中。
import {NgModule} from '@angular/core';import {BrowserModule} from '@angular/platform-browser';import {AppComponent} from "./app.component";import {TaskListComponent} from "./todo/components/task-list.component";import {AboutComponent} from "./about/components/about.components";import {TaskComponent} from "./todo/components/task.component";import {routing, appRoutingProviders} from './app.routing';import {FormsModule} from "@angular/forms";@NgModule({ imports: [ BrowserModule, FormsModule, routing ], declarations: [ AppComponent, TaskComponent, TaskListComponent, AboutComponent ], providers: [ appRoutingProviders ], bootstrap: [AppComponent]})export class AppModule {}
6. Application bootstrap - src/app/main.ts
//import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';import {AppModule} from './app.module';const platform = platformBrowserDynamic();platform.bootstrapModule(AppModule);
构建运行
npm run clean & npm run build npm start
您应该看到应用程序在浏览器中运行
关于IntelliJ的注意事项
IntelliJ处理建议的设置没有问题。如果IntelliJ中使用TypeScript编译器,则应使用该项目的tsconfig.json。在这种情况下,ts文件的更改将立即反映在构建目录中。
代码资源
下一步做什么?
需要更多的实际使用这个项目。因此,很快就会添加更多功能。如果您有任何建议,评论或添加Github问题。
angular2-seed
如果您需要更成熟的启动器,请查看angular2-seed项目
angular2-seed以更先进的方式使用gulp,并且已经支持生产和开发构建,单元和集成测试等等。