[Step-By-Step Angular2](1)Hello World與自動化環境搭建

来源:http://www.cnblogs.com/front-end-ralph/archive/2016/06/09/5572514.html
-Advertisement-
Play Games

隨著rc(release candidate,候選版本)版本的推出,萬眾矚目的angular2終於離正式發佈不遠啦!五月初舉辦的ng-conf大會已經過去了整整一個月,大多數api都如願保持在了相對穩定的狀態——當然也有router這樣的例外,在rc階段還在大面積返工,讓人頗為不解——不過總得說來, ...


隨著rc(release candidate,候選版本)版本的推出,萬眾矚目的angular2終於離正式發佈不遠啦!五月初舉辦的ng-conf大會已經過去了整整一個月,大多數api都如願保持在了相對穩定的狀態——當然也有router這樣的例外,在rc階段還在大面積返工,讓人頗為不解——不過總得說來,現在學習angular2不失為一個恰當的時機。

Google為angular2準備了完善的文檔和教程,按理說,官網(https://angular.io)自然是學習新框架的最好教材。略顯遺憾的是,在Basic章節的Overview部分中,作者在開篇就明確提到這是一份準備給有經驗的開發者的一份文檔(This is a practical guide to Angular for experienced programmers who are building client applications in HTML and TypeScript)。換言之,如果要較好地理解官網上的文檔和教程,對閱讀者是有一定要求的。最顯而易見的是,在angular2中,連運行入門級的hello world都需要配置編譯環境和後端支持——別忘了,即使是去年火遍大江南北的react,我們在學習hello world時還能通過script引入babel來在運行時解析jsx呢(當然在生產環境上可不能這麼乾)。如果要細數下來,要求就更多了:node和npm、webpack或者systemjs之類的打包和模塊化工具、面向對象編程、es6的基本語法和概念、Web Components等新標準……

博主在新技術新框架面前並不是一個因循守舊的人,只是有一點讓我比較擔憂:如果angular2的入門門檻太高,那對以後的框架推廣和社區發展會不會有一些不利的影響呢?出於這個想法,博主決定推出一個step by step的博客系列,希望將angular2帶給更多感興趣、但可能暫時缺少相關開發經驗的同學。

下麵就是本系列博客的第一篇:Hello World與自動化環境搭建。

官網在quickstart中使用了systemjs、lite-server,配置較為複雜;為了簡單起見,本文將使用大家更熟悉的gulp、browserify方案。出於相同的目的,編譯的目標版本將選擇es6而非es5,所以請讀者在繼續閱讀之前請確保已經將chrome升級到最新版本。另外,node環境也請先安裝好,具體步驟這裡就不贅述了。

 

1. 創建項目,初始化package.json
創建一個新文件夾angular2-learn,然後使用輸入npm init命令初始化npm環境。

npm init

如果沒有特殊需求,這裡可以一直使用回車鍵,直到整個過程完成。此時查看angular2-learn文件夾,應該多了一個package.json文件,它最重要的作用之一是保存當前項目所需要的依賴。

 

2. 使用npm安裝運行依賴
在正式開發之前,我們需要將angular2的相關類庫下載到本地,以便於之後的打包和運行。在本篇教程中,我們暫時只需要如下幾個依賴:@angular/common, @angular/compiler, @angular/core, @angular/platform-browser, @angular/platform-browser-dynamic
在angular2-learn文件夾下,執行如下命令:

npm install --save @angular/common @angular/compiler @angular/core @angular/platform-browser @angular/platform-browser-dynamic --registry=https://registry.npm.taobao.org

執行完成後,再檢查angular2-learn目錄,發現多了node_modules文件夾,裡面就是剛剛通過npm install安裝的依賴。
package.json的dependencies欄位下也多了很多記錄,這是--save參數的作用:如果沒有--save參數,這些文件依舊會被下載下來,但是不會被保存到package.json中。
--registry參數用於指定npm的鏡像倉庫,由於網路被牆,不使用--registry很多時候都無法完成下載;registry.npm.taobao.org是阿裡給廣大前端同學的福利,長期維護且高速穩定,在這裡順便也向阿裡的同學說一聲謝謝 :)

 

3. 安裝gulp和其他開發依賴
在上一步中,我們下載了angular2框架,angular2框架是程式運行時所依賴的。但是我們在編譯時還需要一些其他的類庫或框架支持。
首先是gulp,我們要靠它完成編譯流程的自動化,比如檢測文件修改、自動編譯、生成目標js等。
我們還需要browserify,因為angular2和大多數托管在npm的類庫遵循的都是commonjs標準而非amd標準,它們適用於nodejs環境而非瀏覽器環境。browserify,正如它的名字所暗示的一樣,可以幫助我們把符合commonjs標準的代碼“瀏覽器化”,使之成為符合amd標準的代碼。
當然我們也需要typescript編譯器。博主本來想用非模塊化的angular2框架以及原生javascript來為大家演示angular2 hello world的例子,但是嘗試後發現,這樣做雖然看起來簡單一些,但實在是味同嚼蠟——缺少了模塊化和元信息註解的支持,angular2的韻味一下就掉了一大半。因此這裡我們還是堅持用typescript作為編程語言,可以預見的是,angular2團隊將來會把大部分精力花在typescript的相關支持上,typescript一定是angular2的預設推薦語言。對於不熟悉typescript的同學,其實也不用擔心,typescript是javascript的超集,所有合法的javascript代碼都是合法的typescript代碼,只要面向對象的基礎比較扎實,學習起來會有一脈相承的感覺,曲線不會太陡峭。
首先來安裝gulp

npm install -g gulp --registry=https://registry.npm.taobao.org

註意,這一步中我們使用了-g而非--save參數。這是因為gulp安裝在全局,並不是為某個特定項目安裝的,g指的就是global。Linux和Mac環境下的讀者在這一步時請註意讀寫許可權問題。
然後回到angular2-learn文件夾,為項目安裝編譯時依賴:

npm install --save-dev gulp gulp-browserify gulp-typescript --registry=https://registry.npm.taobao.org

這裡為什麼使用--save-dev而非--save呢?因為這些工具只在腳本編譯的時候使用,最終生成的js並沒有它們的身影,因此只能算作開發依賴。
安裝完成後檢查package.json,發現剛剛的幾個工具都被加到了devDependencies欄位。
到這裡我們就完成了hello world例子所依賴的類庫的安裝。

 

4. 配置gulpfile.js
正如上文所提到的,我們使用gulp的目的是搭建自動化的編譯環境,使之產出可以在瀏覽器中運行的js代碼。更詳細地說,我們需要gulp檢測ts(typescript腳本的預設尾碼名)文件的變化,一旦有變化發生(比如新建、修改、刪除等),就使用gulp-typescript將腳本從typescript編譯為javascript;由於angular2本身遵循的是適用於nodejs的commonjs標準,從typescript編譯為javascript腳本後,我們還需要使用browserify將它轉變為符合amd標準的javascript文件。流程見下圖:

按照這個思路,我們可以寫出如下gulpfile.js,並將其放到angular2-learn目錄下:

var gulp = require('gulp');
var typescript = require('gulp-typescript');
var browserify = require('gulp-browserify');

gulp.task('compile', function () {
    gulp.src('app/**.ts')
        // typescript編譯配置信息
        .pipe(typescript({
            target: 'es6',
            module: 'commonjs',
            moduleResolution: 'node',
            sourceMap: true,
            emitDecoratorMetadata: true,
            experimentalDecorators: true,
            removeComments: false,
            noImplicitAny: false
        }))
        .on('error', function () {
            console.log('unhandled error from typescript compilation');
        })
        // 將typescript編譯後的javascript文件存放到out目錄下
        .pipe(gulp.dest('./out'))
        .on('end', function () {
            console.log('typescript compilation done');
            // 將main.js作為入口文件,使用browserify按amd規範進行合併
            gulp.src('out/main.js') 
                .pipe(browserify())
                .on('error', function (error) {
                    console.log('unhandled error from browserify resolution');
                    console.log(error);
                })
                // 將browserify後的文件放到項目根目錄
                .pipe(gulp.dest('./')) 
                .on('end', function () {
                    console.log('browserify work done');
                });
        });
});

gulp.task('default', ['compile'], function () {
    gulp.watch('app/**.ts', ['compile']);
});

不熟悉gulp的同學也不用緊張,這個配置文件其實就是為了表達出上圖中的編譯流程。另外,在typescript編譯配置部分,這裡除了將target設為es6和官網不同外,其餘配置都是使用的angular2推薦的配置。為什麼要編譯到es6而不是es5呢,因為es6的大多數特性新版的瀏覽器已經支持了,而且我們的hello world本身也沒有必要考慮瀏覽器相容性,直接使用es6更為方便。

gulpfile配置好之後,對angular2編譯環境的配置到這裡就結束了。

 

5. 入口組件app.component.ts
接下來我們就進入到angular2 hello world的編碼部分。作為一門新的前端框架,angular2吸收了很多前端社區近年來的發展成果,比如我們馬上就要看到的基於es6的模塊化開發和typescript提供的裝飾器(decorator)。typescript雖然是javascript的超集,但其語言特性並不是天馬行空的,大多數還是javascript正常發展的自然延續,例如裝飾器將來就有很大希望成為新的ecmascript標準的一部分。
好了回到正題。我們先在angular2-learn根目錄下創建app文件夾,作為存放所有typescript腳本的目錄。
然後在app文件夾中創建app.component.ts文件,用於入口組件的定義。
在組件的定義中,我們需要使用到@angular/core模塊中的Component裝飾器。
import {Component} from '@angular/core';

有Java開發經驗的同學會發現裝飾器的使用和註解(annotation)的使用方法十分相似。在Component裝飾器中,我們需要定義兩個屬性,selector和template。selector的作用在於告知angular要在哪些元素上使用這個組件,它本身類似於css選擇器。template是Component對應的模板,在本篇教程可以暫時認為它是html代碼的容器。
@Component({
    selector: 'hello-world',
    template: '<h1>hello world</h1>'
})

最後是AppComponent類的定義。本節中暫時還不需要為其添加額外的屬性,但是作為模塊化開發的一部分,為了將該類暴露給其他的文件,我們需要在類的定義前加上export關鍵字。
export class AppComponent {}

app.component.ts的完整文件內容:

// 從@angular/core中引入Component
import {Component} from '@angular/core';

// Component裝飾器的使用
@Component({
    // selector告知angular在哪裡初始化AppComponent這個組件
    selector: 'hello-world',
    // AppComponent組件的具體模板
    template: '<h1>hello world</h1>'
})
// 定義AppComponent類並將其暴露給外部環境
export class AppComponent {};

 

6. 啟動腳本main.ts
上文中,AppComponent類的定義已經完成了,我們還需要一個類似於C語言main函數或者Java靜態main方法的啟動器來開始angular2的初始化。
依然在app目錄下,這次創建main.ts文件。
angular2在瀏覽器中的啟動依賴於定義在@angular/platform-dynamic-browser上的bootstrap函數。為什麼要將bootstrap定義在這樣一個模塊中而非@angular/core中呢,難道啟動不是核心功能嗎?事實上,angular2這樣做是為瞭解耦框架的核心運行時邏輯和初始化邏輯,方便將來後端、原生移動端上的載入和初始化。
除此以外,我們還需要引入剛剛定義的AppComponent。
main.ts的完整文件內容:

// 從@angular/platform-browser-dynamic引入bootstrap函數
import {bootstrap} from '@angular/platform-browser-dynamic';
// 從app.component.ts引入AppComponent
import {AppComponent} from './app.component';

// 調用bootstrap函數,並將AppComponent作為參數,即入口組件
bootstrap(AppComponent);

上面的代碼中有一個小地方需要註意,引入AppComponent時,from './app.component'中不能寫./app.component.ts,.ts的尾碼必須被省略掉。否則在typescript的編譯完成後,browserify就找不到相應的類而只能拋出異常了。

7. 創建index.html
html!終於來到了本篇教程的最後一個編碼步驟!
由於angular2的部分運行時依賴我們沒有通過gulp打包進去,這裡需要通過cdn載入,當然不嫌麻煩的同學也可以下載到本地。
body里需要放入hello-world標簽,和AppComponent中selector屬性所定義的hello-world相對應。
最後引入gulp編譯、打包結束後生成的在angular2-learn根目錄下的main.js。

index.html的完整內容:

<!doctype html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>angular2-learn</title>
        <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" />
        <script src="http://cdn.bootcss.com/reflect-metadata/0.1.3/Reflect.min.js"></script>
        <script src="http://cdn.bootcss.com/angular.js/2.0.0-beta.17/Rx.umd.min.js"></script>
        <script src="http://cdn.bootcss.com/zone.js/0.6.12/zone.min.js"></script>
    </head>
    <body>
        <hello-world></hello-world>
        <script src="main.js"></script>
    </body>
</html>

 

8. 運行gulp併在瀏覽器中打開
上面的步驟完成後,angular2-learn目錄下的結構應該如圖所示:

在命令行中回到angular2-learn目錄,輸入如下命令並回車:

gulp

如果上面的代碼沒有錯誤,應該可以看見
typescript compilation done
browserify work done
的提示,並且angular2-learn目錄下多了out文件夾和main.js。此時在瀏覽器中打開本地index.html,應該就可以看到最終的效果了。


因為gulp監視了ts文件的變動,如果之後要修改和調試,只需要在browserify work done的提示出來之後刷新網頁即可。

angular2 hello world的例子以及隨後的教程所需要的自動化編譯環境就搭建完啦,對angular2是不是多多少少有了點感覺呢?歡迎繼續閱讀本系列的後續教程。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • ...
  • 一、JSONP 常用的Jquery框架支持jsonp方式請求,該方式只支持GET方法,傳參大小有限,而且需要後臺根據jsonp的請求方式進行封裝結果返回。 其中參數jsonp預設為callback,jsonpCallback為隨機生成的回調函數名,若指定handleRequest,則後臺參數返回時為 ...
  • 一、原生JavaScript編寫tab切換 二、jQuery編寫tab切換 在用jQuery編寫選項卡過程中,重要的事搞清楚 .eq() 和 .index() 的使用方法。 .eq()是jQuery遍歷的一種方法,參數是元素的索引 .index() 。要註意index是基於0開始的;如果index為 ...
  • 部署普通站點 1、首先下載apache24版本,下載地址為http://pan.baidu.com/s/1pLmvDgB; 2、解壓到你的電腦本地目錄,如D:\Apache24(下文配置都會以當前目錄作為參考說明) 3、修改D:\Apache24\conf\目錄下的httpd.conf文件 部署普通 ...
  • JavaScript數組簡介 JavaScript中的數組與其他語言中的數組是不同的,主要體現在: 數組中存儲的各項可以是不同類型的數據 數組的大小是動態變化的,當新增項時或移除項時可以動態的改變大小來容納當前數據項 在JavaScript中創建數組 在JavaScript中創建數組有兩種方式: 其... ...
  • webpack集成了模塊載入和打包等功能 ,這兩年在前端圈越來越手歡迎。平時一般是用requirejs、seajs作為模塊載入用,用grunt/gulp作為前端構建。webpack作為模塊化載入相容了amd/cmd模式,並且作為模塊化的資源可以是js/css/image coffeescript/s ...
  • 概述 上一篇我們介紹了通過構造函數和原型可以實現JavaScript中的“類”,由於構造函數和函數的原型都是對象,所以JavaScript的“類”本質上也是對象。這一篇我們將介紹JavaScript中的一個重要概念原型鏈,以及如何經原型鏈實現JavaScript中的繼承。 C#的繼承 首先,我們簡單... ...
  • ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...