Angular CLI 終極指南

風靈使發表於2018-09-01

Angular CLI 是什麼?

Angular CLI 是一個命令列介面(Command Line Interface),用於實現自動化開發工作流程。它允許你做以下這些事情:

  • 建立一個新的 Angular 應用程式
  • 執行帶有 LiveReload 支援的開發伺服器,以便在開發過程中預覽應用程式
  • 新增功能到現有的 Angular 應用程式
  • 執行應用程式的單元測試
  • 執行應用程式的端到端 (E2E) 測試
  • 構建應用程式

在詳細介紹 Angular CLI 之前,我們先來看一下如何安裝 Angular CLI

前提條件

在使用 Angular CLI 之前,你必須確保系統中 Node.js 的版本高於 6.9.0npm 的版本高於 3.0.0

若你尚未安裝 Node.js,你可以訪問 Node.js 官網,然後根據你所用的作業系統選擇對應的安裝方式。

若你本機已經安裝 Node.jsnpm,你可以通過執行以下命令,確認一下當前環境資訊:

$ node - v # 顯示當前Node.js的版本
$ npm -v # 顯示當前npm的版本

當你本機 Node.js 環境確認無誤後,你可以在命令列使用 npm 安裝 TypeScript

$ npm install -g typescript # 安裝最新的TypeScript穩定版

安裝 Angular CLI

若要安裝 Angular CLI,只需在命令列中執行以下命令:

$ npm install -g @angular/cli

驗證是否成功安裝 Angular CLI,可在命令列執行:

$ ng version

在我本機執行上述命令,則輸出以下結果:

@angular/cli: 1.1.1
node: 6.10.2
os: darwin x64

安裝完 Angular CLI,接下來我們來使用它建立新的應用程式。

建立新的 Angular 應用程式

Angular CLI 為我們提供了兩種方式,用於建立新的應用程式:

  • ng init - 在當前目錄建立新的應用程式
  • ng new - 建立新的目錄,然後在新建的目錄中執行 ng init 命令

因此 ng newng init 的功能是相似的,只是 ng new 會為我們建立新的目錄。

假設你還未建立新的目錄,那麼我們需要使用 ng new 命令來建立新的專案:

$ ng new my-app

當執行上面的命令後,將發生以下事情:

  • 新的 my-app 目錄被建立
  • 應用程式相關的原始檔和目錄將會被建立
  • 應用程式的所有依賴 (package.json中配置的依賴項) 將會被自動安裝
  • 自動配置專案中的 TypeScript 開發環境
  • 自動配置 Karma 單元測試環境
  • 自動配置 Protractor (end-to-end) 測試環境
  • 建立 environment 相關的檔案並初始化為預設的設定

此時 my-app 目錄中 Angular 應用程式的目錄結構如下:

.
├── README.md
├── e2e
│   ├── app.e2e-spec.ts
│   ├── app.po.ts
│   └── tsconfig.e2e.json
├── karma.conf.js
├── package.json
├── protractor.conf.js
├── src
│   ├── app
│   │   ├── app.component.css
│   │   ├── app.component.html
│   │   ├── app.component.spec.ts
│   │   ├── app.component.ts
│   │   └── app.module.ts
│   ├── assets
│   ├── environments
│   │   ├── environment.prod.ts
│   │   └── environment.ts
│   ├── favicon.ico
│   ├── index.html
│   ├── main.ts
│   ├── polyfills.ts
│   ├── styles.css
│   ├── test.ts
│   ├── tsconfig.app.json
│   ├── tsconfig.spec.json
│   └── typings.d.ts
├── tsconfig.json
└── tslint.json

可用選項

  • dry-run: boolean, 預設為 false, 若設定 dry-run 則不會建立任何檔案
  • verbose: boolean, 預設為 false
  • link-cli: boolean, 預設為 false, 自動連結到 @angular/cli 包
  • skip-install: boolean, 預設為 false, 表示跳過 npm install
  • skip-git: boolean, 預設為 false, 表示該目錄不初始化為 git 倉庫
  • skip-tests: boolean, 預設為 false, 表示不建立 tests 相關檔案
  • skip-commit: boolean, 預設為 false, 表示不進行初始提交
  • directory: string, 用於設定建立的目錄名,預設與應用程式的同名
  • source-dir: string, 預設為 ‘src’, 用於設定原始檔目錄的名稱
  • style: string, 預設為 ‘css’, 用於設定選用的樣式語法 (‘css’, ‘less’ or ‘scss’)
  • prefix: string, 預設為 ‘app’, 用於設定建立新元件時,元件選擇器使用的字首
  • mobile: boolean, 預設為 false,表示是否生成 Progressive Web App 應用程式
  • routing: boolean, 預設為 false, 表示新增帶有路由資訊的模組,並新增到根模組中
  • inline-style: boolean, 預設為 false, 表示當建立新的應用程式時,使用內聯樣式
  • inline-template: boolean, 預設為 false, 表示當建立新的應用程式時,使用內聯模板

除此之外,你可以在本機上執行 ng generate --help 檢視更多的可用選項。接下來讓我們來看一下如何執行應用程式。

執行應用程式

首先進入使用 Angular CLI 建立的應用程式目錄,例如:

$ cd my-app

然後執行:

$ ng serve

當執行上面的命令後,將發生以下事情:

  • Angular CLI 從 .angular-cli.json 檔案中載入配置資訊
  • Angular CLI 執行 Webpack 打包相關 JavaScript 和 CSS 檔案
  • Angular CLI 啟動 webpack dev server 本地開發伺服器,預設的地址是localhost:4200

若要停止應用程式,你可以使用 ctrl+c 快捷鍵。

新增功能到現有的 Angular 應用程式

你可以使用 ng generate 命令,為已有的 Angular 應用程式新增新的功能。

  • ng generate class my-new-class: 新建 class
  • ng generate component my-new-component: 新建元件
  • ng generate directive my-new-directive: 新建指令
  • ng generate enum my-new-enum: 新建列舉
  • ng generate module my-new-module: 新建模組
  • ng generate pipe my-new-pipe: 新建管道
  • ng generate service my-new-service: 新建服務

    ng generate 命令與其它的子命令一樣,也有快捷鍵,具體如下:

  • ng g cl my-new-class: 新建 class

  • ng g c my-new-component: 新建元件
  • ng g d my-new-directive: 新建指令
  • ng g e my-new-enum: 新建列舉
  • ng g m my-new-module: 新建模組
  • ng g p my-new-pipe: 新建管道
  • ng g s my-new-service: 新建服務
  • -

新增新的類

為了新增類名為 UserProfile 類,我們可以執行:

$ ng generate class user-profile

Angular CLI 會自動調整檔名和類名的字母大小寫,因此以下命令具有相同的效果:

$ ng generate class user-profile
$ ng generate class userProfile
$ ng generate class UserProfile

執行上述命令後,在幕後將發生以下事情:

  • src/app 目錄下將建立一個 user-profile.ts 檔案,該檔案匯出一個名為 UserProfile 的類

可用選項

  • --spec: boolean, 預設為 false, 表示是否生成單元測試相關的 spec 檔案

使用示例

# Generate class 'UserProfile'
$ ng generate class user-profile

# Generate class 'UserProfile' with unit test
$ ng generate class user-profile --spec

新增新的元件

若想建立一個選擇器為 app-site-header 的元件,則可以執行:

$ ng generate component site-header
installing component
  create src/app/site-header/site-header.component.css
  create src/app/site-header/site-header.component.html
  create src/app/site-header/site-header.component.spec.ts
  create src/app/site-header/site-header.component.ts
  update src/app/app.module.ts

將自動調整檔名和元件名稱的字母大小寫,並將字首應用於元件選擇器,因此以下命令具有相同的效果:

$ ng generate component site-header
$ ng generate component siteHeader
$ ng generate component SiteHeader

執行上述命令後,在幕後將發生以下事情:

  • src/app/site-header 目錄被建立
  • site-header 目錄下會生成以下四個檔案:
  • CSS 樣式檔案,用於設定元件的樣式
  • HTML 模板檔案,用於設定元件的模板
  • TypeScript 檔案,裡面包含一個 SiteHeaderComponent 元件類和元件的元資訊
  • Spec 檔案,包含元件相關的測試用例
  • SiteHeaderComponent 元件會被自動地新增到最近模組 @NgModule 裝飾器的 declarations 屬性中。

可用選項

  • --flat: boolean, 預設為 false, 表示在 src/app 目錄下生成元件而不是在 src/app/site-header 目錄中
  • --inline-template: boolean, 預設為 false, 表示使用內聯模板而不是使用獨立的模板檔案
  • --inline-style: boolean, 預設為 false, 表示使用內聯樣式而不是使用獨立的樣式檔案
  • --prefix: boolean, 預設為 true, 使用 .angular-cli.json 配置的字首作為元件選擇器的字首
  • --spec: boolean, 預設為 true, 表示生成包含單元測試的 spec 檔案
  • --view-encapsulation: string, 用於設定元件的檢視封裝策略
  • --change-detection: string, 用於設定元件的變化檢測策略

使用示例

# Generate component 'site-header'
$ ng generate component site-header

# Generate component 'site-header' with inline template and inline styles
$ ng generate component site-header --inline-template --inline-style

新增新的指令

若想建立一個選擇器為 appAdminLink 的指令,則可以執行:

$ ng generate directive admin-link
installing directive
  create src/app/admin-link.directive.spec.ts
  create src/app/admin-link.directive.ts
  update src/app/app.module.ts

Angular CLI 將自動調整檔名和指令名稱的字母大小寫,並將字首應用於指令選擇器,因此以下命令具有相同的效果:

$ ng generate directive admin-link
$ ng generate directive adminLink
$ ng generate directive AdminLink

執行上述命令後,在幕後將發生以下事情:

  • src/app/admin-link.directive.ts 檔案被建立,該檔案匯出一個名為 AdminLinkDirective且選擇器為 appAdminLink 的指令
  • src/app/admin-link.directive.spec.ts 檔案被建立,該檔案包含指令相關的單元測試資訊
  • AdminLinkDirective 指令會被自動地新增到最近模組 @NgModule 裝飾器的 declarations 屬性中。

可用選項

  • flat: boolean, 預設為 true, 表示在 src/app 目錄中生成指令而不是在 src/app/admin-link 目錄下
  • prefix: boolean, 預設為 true, 使用 .angular-cli.json 配置的字首作為指令選擇器的字首
  • --spec: boolean, 預設為 true, 表示生成包含單元測試的 spec 檔案

使用示例

# Generate directive 'adminLink'
$ ng generate directive admin-link

# Generate directive 'adminLink' without unit test
$ ng generate directive admin-link --spec=false

新增新的列舉

若想建立一個名為 Direction 的列舉類 ,則可以執行:

$ ng generate enum direction
installing enum
  create src/app/direction.enum.ts

Angular CLI 會自動調整檔名和列舉名稱的字母大小寫,因此以下命令具有相同的效果:

$ ng generate enum direction
$ ng generate enum Direction

執行上述命令後,在幕後將發生以下事情:

  • src/app.direction.enum.ts 檔案被建立,該檔案匯出名為 Direction 的列舉

新增新的模組

若想建立一個新的模組 ,則可以執行:

$ ng generate module admin
installing module
  create src/app/admin/admin.module.ts

執行上述命令後,在幕後將發生以下事情:

  • src/app/admin 目錄被建立
  • src/app/admin/admin.module.ts 檔案中,AdminModule 模組被建立

需要注意的是,新增的模組不會被自動新增到 src/app/app.module.ts 檔案中的 AppModule 模組中,使用者可以根據具體需求匯入對應的模組。

若要在其它模組中匯入剛才新增的模組,可以在 @NgModuleimports 屬性中設定該新增的模組。具體示例如下:

import { AdminModule } from './admin/admin.module';

@NgModule({
  // ...
  imports: [
    AdminModule
  ]
})
export class AppModule { }

可用選項

  • routing: boolean, 預設為 false, 表示生成一個額外包含路由資訊的AdminRoutingModule 模組,且該模組會被自動地匯入到新建的模組中
  • --spec: boolean, 預設為 false, 表示新增 src/app/admin/admin.module.spec.ts 單元測試檔案

使用示例

# Add module 'admin'
$ ng generate module admin

# Add module 'admin' with additional module containing routing information
$ ng generate module admin --routing

新增新的管道

若想建立一個名為 convertToEuro 的管道 ,則可以執行:

$ ng generate pipe convert-to-euro
installing pipe
  create src/app/convert-to-euro.pipe.spec.ts
  create src/app/convert-to-euro.pipe.ts
  update src/app/app.module.ts

Angular CLI 會自動調整檔名和管道名稱的字母大小寫,因此以下命令具有相同的效果:

$ ng generate pipe convert-to-euro
$ ng generate pipe convertToEuro
$ ng generate pipe ConvertToEuro

執行上述命令後,在幕後將發生以下事情:

  • src/app/convert-to-euro.pipe.ts 檔案被建立,該檔案匯出一個名為 ConvertToEuroPipe的管道類
  • src/app/convert-to-euro.pipe.spec.ts 檔案被建立,該檔案包含管道相關的單元測試資訊
  • CovertToEuroPipe 管道會被自動地新增到最近模組 @NgModule 裝飾器的 declarations 屬性中。

可用選項

  • --flat: boolean, 預設為 true, 表示在 src/app 目錄中生成管道而不是在 src/app/convert-to-euro 目錄下
  • --spec: boolean, 預設為 true, 表示生成包含單元測試的 spec 檔案

使用示例

# Generate pipe 'convertToEuro' with spec and in /src/app directory
$ ng generate pipe convert-to-euro

# Generate pipe 'convertToEuro' without spec and in /src/app/convert-to-euro directory
$ ng generate pipe convert-to-euro --spec=false --flat=false

新增新的服務

若想建立一個名為 BackendApiService 的服務 ,則可以執行:

$ ng generate service backend-api
installing service
  create src/app/backend-api.service.spec.ts
  create src/app/backend-api.service.ts
  WARNING Service is generated but not provided, it must be provided to be used

Angular CLI 會自動調整檔名和服務名稱的字母大小寫,因此以下命令具有相同的效果:

$ ng generate service backend-api
$ ng generate service backendApi
$ ng generate service BackendApi

執行上述命令後,在幕後將發生以下事情:

  • src/app/backend-api.service 檔案被建立,該檔案匯出一個名為BackendApiService 的服務類
  • src/app/back-api.service.spec.ts 檔案被建立,該檔案包含管道相關的單元測試資訊

需要注意的是,Angular CLI 會提醒使用者服務已成功建立,但尚未配置該服務。使用者可以根據具體需求在模組或元件的 providers 屬性中配置該新建的服務。具體示例如下:

import { BackendApiService } from './backend-api.service';

@NgModule({
  // ...
  providers: [BackendApiService],
  bootstrap: [AppComponent]
})

可用選項

  • --flat: boolean, 預設為 true, 表示在 src/app 目錄中生成服務而不是在 src/app/backend-api 目錄下
  • --spec: boolean, 預設為 true, 表示生成包含單元測試的 spec 檔案

使用示例

# Generate service with DI token 'BackendApiService' in /src/app directory
$ ng generate service backend-api

# Generate service with DI token 'BackendApiService' in /src/app/backend-api directory
$ ng generate service backend-api --flat=false

執行單元測試

Angular CLI 在新建專案的時候,自動為我們整合了 Karma test runner 測試框架。當新增新的功能時,我們可以利用 –spec 選項,告訴 Angular CLI 讓它為我們生成功能相關的 .spec.ts 測試單元測試檔案。

spec 檔案在 src 目錄中相應功能的同一目錄下建立,這使得我們可以在使用功能時輕鬆找到它們。

若要執行單元測試,則可以執行:

$ ng test

此時在你的控制檯將輸出以下資訊:

$ ng test
[karma]: No captured browser, open http://localhost:9876/
[karma]: Karma v1.4.1 server started at http://0.0.0.0:9876/
[launcher]: Launching browser Chrome with unlimited concurrency
[launcher]: Starting browser Chrome

執行上述命令後,在幕後將發生以下事情:

  • Angular CLI 從 .angular-cli.json 檔案中載入配置資訊
  • Angular CLI 基於 .angular-cli.json 檔案中的 Karma 相關的配置資訊,執行 Karma。Karma的配置檔案預設在根目錄下,檔名為 karma.conf.js
  • Karma 開啟配置中設定的瀏覽器,預設是 Chrome
  • Karma 然後指示瀏覽器 (Chrome) 使用 Karma 配置中指定的測試框架執行 src/test.ts。預設情況下,採用的是Jasmine 框架。建立應用程式時,會自動建立 src/test.ts 檔案。它預先配置為載入和配置測試Angular應用程式所需的程式碼,並執行 src 目錄中以 .spec.ts 結尾的所有檔案。
  • Karma 將測試結果報告給控制檯。
  • Karma 監聽 src 目錄下的檔案的變化,然後自動執行單元測試。

執行 End-to-End 測試

若要執行 e2e 測試,則可以執行:

$ ng e2e

構建應用程式
若要構建應用程式,則可以執行:

$ ng build
執行上述命令後,在幕後將發生以下事情:

  • Angular CLI 從 .angular-cli.json 檔案中載入配置資訊
  • Angular CLI 執行 Webpack 打包專案相關的 JavaScript 與 CSS 檔案
  • 打包後的資源,將被輸出到配置檔案中 outDir 所指定的目錄,預設是輸出到 dist 目錄

可用選項

  • --aot: 開啟 ahead-of-time 編譯
  • --base-href: string, 設定 index.html 檔案中 元素的連結地址
  • --environment: string, 設定所使用的環境,預設為 dev
  • --output-path: string, 設定輸出的路徑
  • --target: string, 設定所使用的環境,預設為 development
  • --watch: boolean, 預設為 false, 開啟 watch 模式,監聽檔案異動並自動重新構建

Targets
指定 target 的值,會影響到構建流程的執行方式。它的可選值:

  • development: 預設的模式,意味著不進行程式碼壓縮或混淆
  • production: 壓縮和混淆程式碼

若需使用 production 模式,構建應用程式,則可以執行:

$ ng build --target=production

Environments
Environments 讓你能夠自定義應用程式行為。

你可以在 .angular-cli.json 檔案中定義自己的 environments 檔案。預設的是:

dev:environments/environment.ts
export const environment = {
  production: false
};
  • prod:environments/environment.prod.ts
export const environment = {
  production: true
};

需要注意的是,構建流程預設使用 dev 環境。

如果指定了不同的環境,構建過程將使用相應的環境:

# Uses environments/environment.ts
$ ng build

# Also uses environments/environment.ts
$ ng build --environment=dev
$ ng build --env=dev

# Uses environments/environment.prod.ts
$ ng build --environment=prod
$ ng build --env=prod

正如你在 src/main.ts 檔案中看到的,通過匯入 ./environments/environment 檔案,我們就可以訪問到 environment 相關的配置資訊,具體如下:

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

platformBrowserDynamic().bootstrapModule(AppModule);

自定義構建流程

從 v1.0 開始,Angular CLI 提供了一個命令,用於將你的應用程式與 Angular CLI 分離。

預設情況下,Angular CLI 為您管理基礎 Webpack 配置,因此您無需處理其複雜性。如果你希望手動配置webpack,並且您不再需要在Angular應用程式中使用Angular CLI,則可以執行:

$ ng eject

此時在你的控制檯將輸出以下資訊:

==========================================================================================
Ejection was successful.

To run your builds, you now need to do the following commands:
   - "npm run build" to build.
   - "npm run test" to run unit tests.
   - "npm start" to serve the app using webpack-dev-server.
   - "npm run e2e" to run protractor.

Running the equivalent CLI commands will result in an error.

==========================================================================================
Some packages were added. Please run "npm install".

執行上述命令後,在幕後將發生以下事情:

  • ejected: true 的屬性被新增到 .angular-cli.json 檔案中
  • 在應用程式的根目錄下將生成獨立的 webpack.config.js 檔案,因此你可以在沒有使用 Angular CLI 的環境下構建專案
  • package.json 中的構建指令碼會被更新,因此你可以執行 npm run build 來構建專案
  • package.json 中的測試指令碼會被更新,因此你可以執行 npm run test 來執行單元測試
  • package.json 中的啟動指令碼會被更新,因此你可以執行 npm run startnpm start 來啟動開發伺服器
  • package.json 中的 e2e 指令碼會被更新,因此你可以執行 npm run e2e 來執行 End-to-End 測試

把應用程式與 Angular CLI 分離後,你就可以根據自己的要求自定義 Webpack 的配置。

相關文章