Angular代碼風格

寫在前面

自身的良好編碼風格只能律己,而沒法律人;我喜歡 Angular 其中主要一個因素是有一整套的工具風格指南,它能夠極大的簡化團隊開發溝通成本,可是有些小缺失例如在編碼風格上官方只提供 TypeScript 的部分,對於其餘文件並無一套指南以及智能化。html

VSCode 是我開發 Angular 應用的首選,本文也將以此 IDE 爲基準;任何提到的擴展均可以經過市場來獲取。git

Angular 應用是由組件樹組成,一個組件從文件來看包含:TypeScript、HTML、Less(或其餘 CSS 預處理器),其中 HTML 可能被包含至 ts 文件裏。github

固然除此以外還包含一些 JSON 文件、Bash 文件等,當此部分不在本文討論內。

TSLint

Angular 建立後就已經包含 tslint.json(它是 TSLint 的配置文件),而且全部默認規則都按官方風格指南具體踐行。typescript

而 TSLint 的配置文件,默認使用內置預設 tslint:recommended 版本,並在此基礎上加入 Angular 質量檢查工具 codelyzer,全部這些規則你能夠經過 tslint rulescodelyzer 找到每項規則的說明。npm

規則的寫法要麼是 boolean 類型,或者使用數組對該規則指定額外參數。

運行 ng lint 命令時,當你某個字符串變量使用雙引號,它會提示:json

ERROR: /src/app/app.component.ts[9, 16]: " should be '

咱們也能夠安裝 TSLint 擴展讓這個觸發機制放在正在編碼過程當中實時反饋:數組

  1. 當有不符合風格指南會出現一個綠色的波浪線,按 command+. > Fix: " Should be '
  2. 經過終端 PROBLEMS 面板查看全部已打開文件且不符合風格指南的明細

嗯,讓你按五次 command+. 快捷鍵,我必定會瘋掉;TSLint 擴展支持在保存文件時自動修復,只須要在項目根目錄 .vscode/settings.json 配置:bash

{
  "editor.codeActionsOnSave": {
    "source.fixAll": true
  }
}

配置

tsline.json 有許多規則是針對任何 TypeScript,而 codelyzer 是專門針對 Angular,如下幾個可能你須要認識項:app

directive-selectorcomponent-selectorless

限定 Direcitve、Component 的 selector 選擇器屬性值的風格,默認必須是 app 開頭,有時候對於一些共享型組件設置不一樣的風格,例如一個業務型富文本框 xx-editor,須要在 tslint.json 修改配置:

"directive-selector": [
  true,
  "attribute",
  ["app", "xx"],
  "camelCase"
],
"component-selector": [
  true,
  "element",
  ["app", "xx"],
  "kebab-case"
]

component-class-suffixdirective-class-suffix

指令或組件類名必須是寫駝峯命名法來命名,且必須使用 ComponentDirective 後綴;若團隊可能已經習慣相似 View 做爲後綴,則:

"component-class-suffix": [true, "Component", "View"],
"directive-class-suffix": [true, "Directive", "View"]

use-life-cycle-interface

強制實現生命週期鉤子接口,例如 ngOnInit

export class HeroButtonComponent implements OnInit {
  ngOnInit() {
    console.log('The component is initialized');
  }
}

interface-name

TypeScript 指導原則不建議使用 「I」 前綴;所以建議增長:

"interface-name": [true, "never-prefix"]
// 錯誤寫法
export interface IUser {
  id: number;
}
// 正確寫法
export interface User {
  id: number;
}

美化

TSLint 並不支持美化(雖然有幾個項看起來像是在「美化」),而美化的工做取決於你採用什麼 IDE,例如 VSCode 默認是使用 4 個空格表示一個 Tab 鍵。

EditorConfig

我不建議依賴 IDE 默認的代碼格式配置,因此就有一個 .editorconfig 組織來規範一些簡單的統一規範配置。

Angular 項目時也會有 .editorconfig 的配置,雖然有這個配置文件,但在 VSCode 也有本身的一套規範而且優先級更高,因此要想讓 EditorConfig 生效須要額外安裝 EditorConfig for VS Code 插件。

Editorconfig 只包含一些最基礎的項,要想讓代碼統一風格的美化仍是須要更強大的 Prettier。

Prettier

她支持市場上許多語言,其中包含 TypeScript、HTML、Less 這一些都符合 Angular 項目的必備;你須要引入 prettier 以及 VSCode Prettier - Code formatter 擴展。

配置

在根目錄下建立 .prettierrc 配置文件以及 .prettierignore 忽略美化配置文件;Editorconfig 選項與 Prettier 選項高度重疊,而且後者會強制替換前者,例如:

# .editorconfig
indent_size = 4
# .prettierrc
{
  "tabWidth": 2
}

表示一個 Tab 寬度使用 2 個空格;我我的建議 Prettier 不該該覆蓋 EditorConfig 的部分,它們包含:tabWidthuseTabsendOfLine

而一個簡單的 Prettier 配置差很少這樣:

{
  // 單行最大長度
  "printWidth": 140,
  // 語句末尾添加分號
  "semi": true,
  // 使用單引號而非雙引號
  "singleQuote": true,
  // 尾逗號
  "trailingComma": "all"
}

若是你想忽略一些不想美化的文件,例如 Markdown,則 . prettierignore

*.md

一樣若是你指望每次保存文件時自動美化代碼,只須要在項目根目錄 .vscode/settings.json 配置:

{
  "editor.formatOnSave": true
}

Prettier 與 TSLint

Prettier 配置 項會有部分與 tslint.json 項重複,例如:Prettier 的 printWidthtsline.jsonmax-line-length,對於 Prettier 以她爲優先,反之使用 ng lint 會以 tslint.json 優先。

這對咱們來講有些困惑,TSLint 包含了一些代碼」美化性"(例如:max-line-length),事實上,這更應該是 Prettier 的專長(全部配置都跟代碼美化相關)。

tslint-config-prettier

好在 tslint-config-prettier 幫助清理這些可能會產生衝突規則的解決方案:

"extends": [
  "tslint:recommended",
  "tslint-config-prettier"
]

prettier 提供一種檢查機制:

tslint-config-prettier-check ./tslint.json

你會發現默認的 Angular 項目中會有 max-line-lengthobject-literal-key-quotesquotemark 三項是衝突的,咱們能夠關掉 tsline.json 這三項的配置,讓 Prettier 來代替。

{
  "rules": {
    "max-line-length": [false, 140],
    "object-literal-key-quotes": [false, "as-needed"],
    "quotemark": [false, "single"]
  }
}

HTML

Prettier 默認會自動識別 Angular 項目並使用其引擎,固然也包含對 templatetemplateUrl 兩種寫法。

printWidth

會決定一段 HTML 超出長度範圍後屬性會自動換行:

<h1 style="color: #f50;" data-long="long" data-long-long="long" data-long-long-long="long" data-long-long-long-long="long">
  Share Component
</h1>

變成:

<h1
  style="color: #f50;"
  data-long="long"
  data-long-long="long"
  data-long-long-long="long"
  data-long-long-long-long="long"
>
  Share Component
</h1>

htmlWhitespaceSensitivity

空白敏感這一點同 Angular 的 preserveWhitespaces 相似,若是你的 Angular 項目配置了 preserveWhitespaces: false 則無須理會;反之設定不一樣的參數會影響美化的效果,若項目對空白敏感有需求能夠設定爲 strict 會強制清除空白,例如:

<h1
  style="color: #f50;"
  data-long="long"
  data-long-long="long"
  data-long-long-long="long"
  data-long-long-long-long="long"
  >Share Component</h1
>

Less

無論哪一種 CSS 預處理器均可以使用 stylelint 做爲代碼檢查工具,安裝 stylelintstylelint-config-standard 並在根目錄 .stylelintrc 配置:

{
  "extends": [ "stylelint-config-standard" ],
  "plugins": [ ],
  "rules": { },
  "ignoreFiles": [ "src/assets/**/*" ]
}

package.json 定義一條:

{
  "scripts": {
    "lint:style": "stylelint 'src/**/*.less' --syntax less"
  }
}

若缺乏 ; 會被收到 Missed semicolon 錯誤:

:host {
  width: 100px;
  height: 100px
  display: block;
}
src/app/app.component.less
 3:11  ✖  Missed semicolon   CssSyntaxError
stylelint 有本身的一套 規則,而 stylelint-config-standard 只是官方提供一種 默認規則

Prettier

前面提到 Prettier 也支持 Less,須要額外安裝依賴包 prettier-stylelint ,並修改 .stylelintrc 配置:

{
  "extends": [
    "stylelint-config-standard",
    "stylelint-config-prettier"
  ],
  "plugins": [ ],
  "rules": {
    "selector-type-no-unknown": [
      true,
      {
        "ignoreTypes": [
          "/^app-/"
        ]
      }
    ],
    "selector-pseudo-element-no-unknown": [
      true,
      {
        "ignorePseudoElements": [
          "ng-deep"
        ]
      }
    ]
  },
  "ignoreFiles": [ "src/assets/**/*" ]
}

可是依然沒法生效,因爲在 VSCode 下面 EditorConfig for VS Code 擴展默認並無開啓它,在 .vscode/settings.json 增長:

{
  "prettier.stylelintIntegration": true
}

加上以前已經開啓保存時自動修復功能,一樣也適用 Less 即保存時根據 .stylelintrc 配置修復及美化。

一些有趣的插件

stylelint-config-rational-order

Css 語言同一類型的相關屬性可能會不少,而將這些相關屬性進行分組對於維護很是有幫助,安裝 stylelint-orderstylelint-config-rational-order,並修改 .stylelintrc 配置:

{
  "extends": [
    "stylelint-config-standard",
    "stylelint-config-rational-order",
    "stylelint-config-prettier"
  ],
  "plugins": [
    "stylelint-order"
  ],
  "rules": { },
  "ignoreFiles": [ "src/assets/**/*" ]
}

stylelint-declaration-block-no-ignored-properties

當設置 display: inline 內聯時,此時再寫 width: 100px 是無心義的,而該組件能夠自動移除這種無效屬性。

{
  "plugins": [
    "stylelint-declaration-block-no-ignored-properties"
  ],
  "rules": {
    "plugin/declaration-block-no-ignored-properties": true,
  }
}

智能點

至此,涉及 Angular 所須要的代碼風格運用已所有完結,這些檢查咱們都大多數是依靠 VSCode 編輯器的擴展輔助完成。

事實上,咱們只須要增長几個命令來對整個項目進行檢查,確保整個項目的代碼能按所配置的風格執行。

命令行

{
  "scripts": {
    "lint": "npm run lint:ts && npm run lint:style",
    "lint:ts": "tslint -p tsconfig.app.json -c tslint.json 'src/**/*.ts' --fix",
    "lint:style": "stylelint 'src/**/*.less' --syntax less --fix"
  }
}
tslintstylelint 命令行對應的參數說明,均可以經過上述提供官網找獲得。

運行 npm run lint 能夠對整個項目進行檢查及修復;如有包含 CI 能夠直接使用它。

Git

若是能夠將這一過程在向源碼倉庫提交代碼時進行檢查的話,能夠在向代碼倉儲提交前就發現問題,須要安裝 huskylint-staged,而且修改 package.json

{
  "lint-staged": {
    "src/**/*.ts": [
      "npm run lint:ts",
      "git add"
    ],
    "src/**/*.less": [
      "npm run lint:style",
      "git add"
    ]
  },
  "husky": {
    "hooks": {
      "pre-commit": "lint-staged"
    }
  }
}

當向源碼倉庫 Commit 時會自動先執行命令行纔會 git add

總結

當我寫完最後一節時,Angular8 發佈了正式版;因此我把本來準備的樣板項目 ng-code-style-boilerplatef526a0c) 切換成 Angular8,但徹底適用 Angular7.x 版本。

Angular 風格指南中文版)對於喜好 Angular 是必讀、常讀的文章,它指引團隊更友好的編寫代碼,我的良好編碼風格可能律己,但沒法律人,而這種風格指南能夠減小無差異的團隊溝通。

本文雖然以 Angular 的角度出發,但大部份內容一樣適用 React、Vue 等。

(完)

相關文章
相關標籤/搜索