﻿# 如何透過 Angular CLI 快速將專案全部都轉換成獨立元件架構

從 Angular 14 開始，全新架構**獨立元件**(Standalone Component)騰空出世，帶給 Angular 開發者一個全新感受，用更簡潔的程式碼、更清晰的架構，幫助開發人員架構元件與管理元件之間的依賴關係。而從 Angular 15.2.0 開始，更提供了一個 Schematics (程式碼產生器與編修工具) 可以幫助你快速移轉**傳統元件**為**獨立元件**，甚至於可以連同 AppComponent 也一併轉換成獨立元件，讓整個 Angular 應用程式都變成以**獨立元件**為主。這篇文章我來說說這套工具的使用方式！

![text\_effect\_book\_tshirt\_design\_2nd\_time\_181](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/e2636d24c2b3193a46ab-230806087-177f5ad0-37bf-4222-bc48-3b020282efd8.jpg)

以下我用一段實作過程，幫助大家快速體驗一種開發情境：

1.  建立專案
    
    使用 `ng new` 建立一個名為 `demo1` 的專案，使用 `--routing` 啟用路由功能，使用 `--style=css` 指定用 CSS 撰寫樣式，使用 `--inline-style --inline-template` 將元件的樣式與樣版都寫在 `*.component.ts` 裡。
    
    ```bash
    ng new demo1 --routing --style=css --inline-style --inline-template
    cd demo1
    ```
    
    這個新建立的專案，還是會有一組 AppModule (`src/app/app.module.ts`) 與一個傳統元件的 AppComponent (`src/app/app.component.ts`)。
    
2.  執行 `ng lint` 初始化 ESLint 設定
    
    ```bash
    ng lint
    ```
    
    ![image](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/aab5051895249b6eb802-230802531-186680ec-afc4-4f6f-bdc7-59ca56f74472.png)
    
3.  設定 Coding Style (代碼風格) 自動化設定
    
    我在 [設定 Angular 專案使用 husky 簡化 Git hooks 設定並用 Prettier 統一風格](/post/2021/08/27/Angular-husky-Git-hooks-Prettier-formatter) 文章，已經被 Mike 濃縮成一個 `ng add` 命令，直接執行就可以自動將整篇文章的內容一次設定好。
    
    ```bash
    ng add ngx-prettier-git-hooks
    ```
    
    這個命令等同於執行了以下幾個動作：
    
    ```bash
    # 1. 安裝必要套件
    npm install --save-dev husky pretty-quick
    # 2. 設定 scripts.prepare 指令
    npm pkg set scripts.prepare="husky install"
    # 3. 設定 pre-commit Hook
    npx husky set .husky/pre-commit "npx pretty-quick --staged"
    # 4. 新增 .prettierignore 與 .prettierrc.json 設定檔
    # 5. 新增 .vscode/settings.json 與 .vscode/extensions.json 設定檔
    # 6. 執行 npm install 命令(也會一並執行 npm run prepare 命令)
    npm install
    ```
    
    檢查是否有檔案需要格式化
    
    ```bash
    npx prettier --check .
    ```
    
    強制格式化所有檔案
    
    ```bash
    npx prettier --write .
    ```
    
4.  建立一個 HeaderComponent 傳統元件
    
    ```bash
    ng g c header
    ```
    
    跟以往一樣，建立新元件時，會一併註冊到 AppModule (`src/app/app.module.ts`) 之中：
    
    ![image](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/4e288859e17b5acaeacd-230802589-43e0c59c-3cb1-4926-bd5b-a7f18b9659a4.png)
    
    我記得跟 Mike 有過一段這樣的對話：😆
    
    ```
    Will: 我覺得 NgModule 有個缺點，對新手很不友善，就是每個新的 Component 都要註冊在 NgModule 裡面
    Mike: 其實都用 Angular CLI，新手應該也沒感覺？
    Will: 建錯要改的時候，就有感覺了
    Mike: 這倒是真的 XD
    ```
    
5.  利用 `@angular/core:standalone` 這個 Schematics 轉換所有元件為獨立元件
    
    ```bash
    ng generate @angular/core:standalone --path ./ --mode=convert-to-standalone
    ```
    
    執行完就先 build 看看有沒有錯誤
    
    ```bash
    ng build
    ```
    
6.  利用 `@angular/core:standalone` 嘗試移除是否有無用的 NgModules
    
    ```bash
    ng generate @angular/core:standalone --path ./ --mode=prune-ng-modules
    ```
    
    執行完就先 build 看看有沒有錯誤
    
    ```bash
    ng build
    ```
    
7.  利用 `@angular/core:standalone` 嘗試將整個應用程式連同根元件一起改用獨立元件
    
    ```bash
    ng generate @angular/core:standalone --path ./ --mode=standalone-bootstrap
    ```
    
    執行完就先 build 看看有沒有錯誤
    
    ```bash
    ng build
    ```
    
8.  重新檢查現有專案的程式碼風格
    
    統一程式碼排版
    
    ```bash
    npx prettier --check .
    npx prettier --write .
    ```
    
    程式碼風格檢查
    
    ```bash
    ng lint
    ```
    

### 總結

即便 `@angular/core:standalone` 這個 Schematics 可以幫我們轉換所有元件為獨立元件，也真的很佛心，但是凡事總有那 1% 對吧？如果真的遇到了問題，很有可能就是踩到了這個工具的限制([Limitations](https://angular.io/guide/standalone-migration#limitations))，不得不小心謹慎，記得做每個步驟都要 `ng build` 看看有沒有問題。

### 相關連結

-   [Getting started with standalone components](https://angular.io/guide/standalone-components)
    -   [獨立元件入門](https://angular.tw/guide/standalone-components)
-   [Migrate an existing Angular project to standalone](https://angular.io/guide/standalone-migration)
-   [angular/README.md at main · angular/angular · GitHub](https://github.com/angular/angular/blob/main/packages/core/schematics/ng-generate/standalone-migration/README.md)
