鍍金池/ 教程/ HTML/ 創(chuàng)建簡單工程
初始化項目結構
聯合類型
介紹
介紹
介紹
編譯選項
TypeScript 1.6
介紹
介紹
發(fā)展路線圖
介紹
在MSBuild里使用編譯選項
可迭代性
TypeScript 1.3
介紹
介紹
TypeScript 1.1
變量聲明
即將到來的Angular 2框架是使用TypeScript開發(fā)的。 因此Angular和TypeScript一起使用非常簡單方便
tsconfig.json
介紹
介紹
介紹
在MSBuild里使用編譯選項
使用TypeScript的每日構建版本
新建工程
枚舉
三斜線指令
結合ASP.NET v5使用TypeScript
TypeScript里的this
介紹
TypeScript 1.4
編碼規(guī)范
介紹
模塊解析
ASP.NET 4
架構概述
介紹
介紹
ASP.NET Core
TypeScript 1.8
介紹
介紹
創(chuàng)建簡單工程
TypeScript 1.7
TypeScript 1.5
NPM包的類型
支持TypeScript的編輯器

創(chuàng)建簡單工程

我們首先創(chuàng)建一個新目錄。 命名為proj,也可以使用任何你喜歡的名字。

mkdir proj
cd proj

我們將以下面的結構開始我們的工程:

proj/
    +- src/
    +- dist/

TypeScript文件放在src文件夾下,經過TypeScript編譯器編譯生成的目標文件放在dist目錄下。

下面讓我們來創(chuàng)建這些文件夾:

mkdir src
mkdir dist

初始化工程

現在讓我們把這個文件夾轉換成npm包:

npm init

你將看到有一些提示操作。

除了入口文件外,其余的都可以使用默認項。 入口文件使用./dist/main.js。

你可以隨時在package.json文件里更改生成的配置。

安裝依賴項

現在我們可以使用npm install命令來安裝包。 首先全局安裝TypeScript和Gulp。

(如果你正在使用Unix系統(tǒng),你可能需要使用sudo命令來啟動npm install命令行。)

npm install -g typescript gulp-cli

然后安裝gulpgulp-typescript到開發(fā)依賴項。

Gulp-typescript是TypeScript的一個Gulp插件。

npm install --save-dev gulp gulp-typescript

寫一個簡單的例子

讓我們寫一個Hello World程序。

src目錄下創(chuàng)建main.ts文件:

function hello(compiler: string) {
    console.log(`Hello from ${compiler}`);
}
hello("TypeScript");

在工程的根目錄proj下新建一個tsconfig.json文件:

{
    "files": [
        "src/main.ts"
    ],
    "compilerOptions": {
        "noImplicitAny": true,
        "target": "es5"
    }
}

新建gulpfile.js文件

在工程根目錄下,新建一個gulpfile.js文件:

var gulp = require("gulp");
var ts = require("gulp-typescript");
var tsProject = ts.createProject("tsconfig.json");

gulp.task("default", function () {
    return tsProject.src()
        .pipe(ts(tsProject))
        .js.pipe(gulp.dest("dist"));
});

測試這個應用

gulp
node dist/main.js

程序應該能夠打印出“Hello from TypeScript!”。

向代碼里添加模塊

在使用Browserify前,讓我們先構建一下代碼然后再添加一些混入的模塊。

這個結構將是你在真實應用程序中會用到的。

新建一個src/greet.ts文件:

export function sayHello(name: string) {
    return `Hello from ${name}`;
}

更改src/main.ts代碼,從greet.ts導入sayHello

import { sayHello } from "./greet";

console.log(sayHello("TypeScript"));

最后,將src/greet.ts添加到tsconfig.json

{
    "files": [
        "src/main.ts",
        "src/greet.ts"
    ],
    "compilerOptions": {
        "noImplicitAny": true,
        "target": "es5"
    }
}

確保執(zhí)行gulp后模塊是能工作的,在Node.js下進行測試:

gulp
node dist/main.js

注意,即使我們使用了ES2015的模塊語法,TypeScript還是會生成Node.js使用的CommonJS模塊。

我們在這個教程里會一直使用CommonJS模塊,但是你可以通過修改module選項來改變這個行為。

Browserify

現在,讓我們把這個工程由Node.js環(huán)境移到瀏覽器環(huán)境里。 因此,我們將把所有模塊捆綁成一個JavaScript文件。 所幸,這正是Browserify要做的事情。

更方便的是,它支持Node.js的CommonJS模塊,這也正是TypeScript默認生成的類型。

也就是說TypeScript和Node.js的設置不需要改變就可以移植到瀏覽器里。

首先,安裝Browserify,tsify和vinyl-source-stream。

tsify是Browserify的一個插件,就像gulp-typescript一樣,它能夠訪問TypeScript編譯器。

vinyl-source-stream會將Browserify的輸出文件適配成gulp能夠解析的格式,它叫做vinyl。

npm install --save-dev browserify tsify vinyl-source-stream

新建一個頁面

src目錄下新建一個index.html文件:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Hello World!</title>
    </head>
    <body>
        <p id="greeting">Loading ...</p>
        <script src="bundle.js"></script>
    </body>
</html>

修改main.ts文件來更新這個頁面:

import { sayHello } from "./greet";

function showHello(divName: string, name: string) {
    const elt = document.getElementById(divName);
    elt.innerText = sayHello(name);
}

showHello("greeting", "TypeScript");

showHello調用sayHello函數更改頁面上段落的文字。 現在修改gulpfile文件如下:

var gulp = require("gulp");
var browserify = require("browserify");
var source = require('vinyl-source-stream');
var tsify = require("tsify");
var paths = {
    pages: ['src/*.html']
};

gulp.task("copy-html", function () {
    return gulp.src(paths.pages)
        .pipe(gulp.dest("dist"));
});

gulp.task("default", ["copy-html"], function () {
    return browserify({
        basedir: '.',
        debug: true,
        entries: ['src/main.ts'],
        cache: {},
        packageCache: {}
    })
    .plugin(tsify)
    .bundle()
    .pipe(source('bundle.js'))
    .pipe(gulp.dest("dist"));
});

這里增加了copy-html任務并且把它加作default的依賴項。 這樣,當default執(zhí)行時,copy-html會被首先執(zhí)行。

我們還修改了default任務,讓它使用tsify插件調用Browserify,而不是gulp-typescript。

方便的是,兩者傳遞相同的參數對象到TypeScript編譯器。

調用bundle后,我們使用source(vinyl-source-stream的別名)把輸出文件命名為bundle.js。

測試此頁面,運行gulp,然后在瀏覽器里打開dist/index.html。 你應該能在頁面上看到“Hello from TypeScript”。

注意,我們?yōu)锽roswerify指定了debug: true。

這會讓tsify在輸出文件里生成source maps。 source maps允許我們在瀏覽器中直接調試TypeScript源碼,而不是在合并后的JavaScript文件上調試。

你要打開調試器并在main.ts里打一個斷點,看看source maps是否能工作。

當你刷新頁面時,代碼會停在斷點處,從而你就能夠調試greet.ts

Watchify,Babel和Uglify

現在代碼已經用Browserify和tsify捆綁在一起了,我們可以使用Browserify插件為構建添加一些特性。

  • Watchify啟動Gulp并保持運行狀態(tài),當你保存文件時自動編譯。 幫你進入到編輯-保存-刷新瀏覽器的循環(huán)中。

  • Babel是個十分靈活的編譯器,將ES2015及以上版本的代碼轉換成ES5和ES3。 你可以添加大量自定義的TypeScript目前不支持的轉換器。

  • Uglify幫你壓縮代碼,將花費更少的時間去下載它們。

Watchify

我們啟動Watchify,讓它在后臺幫我們編譯:

npm install --save-dev watchify gulp-util

修改gulpfile文件如下:

var gulp = require("gulp");
var browserify = require("browserify");
var source = require('vinyl-source-stream');
var watchify = require("watchify");
var tsify = require("tsify");
var gutil = require("gulp-util");
var paths = {
    pages: ['src/*.html']
};

var watchedBrowserify = watchify(browserify({
    basedir: '.',
    debug: true,
    entries: ['src/main.ts'],
    cache: {},
    packageCache: {}
}).plugin(tsify));

gulp.task("copy-html", function () {
    return gulp.src(paths.pages)
        .pipe(gulp.dest("dist"));
});

function bundle() {
    return watchedBrowserify
        .bundle()
        .pipe(source('bundle.js'))
        .pipe(gulp.dest("dist"));
}

gulp.task("default", ["copy-html"], bundle);
watchedBrowserify.on("update", bundle);
watchedBrowserify.on("log", gutil.log);

共有三處改變,但是需要你略微重構一下代碼。

  1. browserify實例包裹在watchify的調用里,控制生成的結果。
  2. 調用watchedBrowserify.on("update", bundle);,每次TypeScript文件改變時Browserify會執(zhí)行bundle函數。
  3. 調用watchedBrowserify.on("log", gutil.log);將日志打印到控制臺。

(1)和(2)在一起意味著我們要將browserify調用移出default任務。

然后給函數起個名字,因為Watchify和Gulp都要調用它。

(3)是可選的,但是對于調試來講很有用。

現在當你執(zhí)行gulp,它會啟動并保持運行狀態(tài)。

試著改變main.ts文件里showHello的代碼并保存。

你會看到這樣的輸出:

proj$ gulp
[10:34:20] Using gulpfile ~/src/proj/gulpfile.js
[10:34:20] Starting 'copy-html'...
[10:34:20] Finished 'copy-html' after 26 ms
[10:34:20] Starting 'default'...
[10:34:21] 2824 bytes written (0.13 seconds)
[10:34:21] Finished 'default' after 1.36 s
[10:35:22] 2261 bytes written (0.02 seconds)
[10:35:24] 2808 bytes written (0.05 seconds)

Uglify

首先安裝Uglify。

因為Uglify是用于混淆你的代碼,所以我們還要安裝vinyl-buffer和gulp-sourcemaps來支持sourcemaps。

npm install --save-dev gulp-uglify vinyl-buffer gulp-sourcemaps

修改gulpfile文件如下:

var gulp = require("gulp");
var browserify = require("browserify");
var source = require('vinyl-source-stream');
var tsify = require("tsify");
var uglify = require('gulp-uglify');
var sourcemaps = require('gulp-sourcemaps');
var buffer = require('vinyl-buffer');
var paths = {
    pages: ['src/*.html']
};

gulp.task("copy-html", function () {
    return gulp.src(paths.pages)
        .pipe(gulp.dest("dist"));
});

gulp.task("default", ["copy-html"], function () {
    return browserify({
        basedir: '.',
        debug: true,
        entries: ['src/main.ts'],
        cache: {},
        packageCache: {}
    })
    .plugin(tsify)
    .bundle()
    .pipe(source('bundle.js'))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: true}))
    .pipe(uglify())
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest("dist"));
});

注意uglify只是調用了自己—buffersourcemaps的調用是用于確保sourcemaps可以工作。

這些調用讓我們可以使用單獨的sourcemap文件,而不是之前的內嵌的sourcemaps。

你現在可以執(zhí)行gulp來檢查bundle.js是否被壓縮了:

gulp
cat dist/bundle.js

Babel

首先安裝Babelify。

和Uglify一樣,Babelify也會混淆代碼,因此我們也需要vinyl-buffer和gulp-sourcemaps。

npm install --save-dev babelify vinyl-buffer gulp-sourcemaps

修改gulpfile文件如下:

var gulp = require('gulp');
var browserify = require('browserify');
var source = require('vinyl-source-stream');
var tsify = require('tsify');
var sourcemaps = require('gulp-sourcemaps');
var buffer = require('vinyl-buffer');
var paths = {
    pages: ['src/*.html']
};

gulp.task('copyHtml', function () {
    return gulp.src(paths.pages)
        .pipe(gulp.dest('dist'));
});

gulp.task('default', ['copyHtml'], function () {
    return browserify({
        basedir: '.',
        debug: true,
        entries: ['src/main.ts'],
        cache: {},
        packageCache: {}
    })
    .plugin(tsify)
    .transform("babelify")
    .bundle()
    .pipe(source('bundle.js'))
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: true}))
    .pipe(sourcemaps.write('./'))
    .pipe(gulp.dest('dist'));
});

我們需要設置TypeScript目標為ES2015。

Babel稍后會從TypeScript生成的ES2015代碼中生成ES5。 修改tsconfig.json:

{
    "files": [
        "src/main.ts"
    ],
    "compilerOptions": {
        "noImplicitAny": true,
        "target": "es2015"
    }
}

對于這樣一段簡單的代碼來說,Babel的ES5輸出應該和TypeScript的輸出相似。