起源
做為跨平臺的移動端解決方案,Flutter大大提高了移動端的開發效率,但是由于很多開發者都是從原來做原生的iOS或者Android開發轉而成為Flutter開發者,而移動端的原生開發語言OC/Swift/Java/Kotlin的代碼規范千差萬別。那如何在Flutter開發過程中,統一代碼規范,提高代碼質量就是一個不小的問題。
Dart代碼規范
Flutter的開發語言Dart有官方的代碼靜態檢查工具—lints,同時lints中內置了上百條的代碼規范,檢查的規范類別包括:可能的拼寫錯誤、代碼風格和代碼的布局等等。這些規范分為兩類:Core lints(核心規范)、Recommended lints(推薦規范)。
Core lints幫助識別出可能在代碼運行時帶來嚴重問題的代碼。所有的代碼應該都通過這些代碼規范檢查。
Recommended lints 包含Core lints,除了Core lints的檢查外,Recommended lints主要是為了規范代碼的風格和布局,讓開發者以一種風格來開發Dart工程。
除了預定義的這兩種規范,開發者還可以在lints中自定義規范。
Flutter代碼規范
雖然Dart有自己的代碼檢查規范,但是Flutter官方更推薦使用為了Flutter而定制的代碼靜態檢查工具—flutter lints。Flutter lints包含了一系列的開發Flutter app、package和plugin的推薦代碼規范。他是在上面所說的Dart的Recommended lints的基礎上進行的改進和對Flutter的適配。
對于在使用Flutter 2.3.0以上的SDK通過flutter creat創建的Flutter app、package和plugin中,flutter lints默認會集成到代碼里。
對于已經存在的Flutter 工程來說,集成flutter lints也是非常簡單的。
- 在Flutter工程的目錄下,運行如下命令
flutter pub add –dev flutter_lints
- 在flutter工程的根目錄下創建一個名為analysis_option.yaml的文件,并且在文件中輸入 include: package:flutter_lints/flutter.yaml
下面是一個analysis_option.yaml文件的例子:
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
增加規則
除了使用flutter lints中的默認規則,開發者也可以增加一些規則,常見的規則可以在Flutter編程規范中有詳細闡述。這些規則中,可能有些規則之間是相互沖突的。某些規則可能更適合于package的開發者,有些可能更適合于flutter app的開的者。
在默認的規則中,代碼檢查的規則如下:
include: package:lints/recommended.yaml linter: rules:
- avoid_print
- avoid_unnecessary_containers
- avoid_web_libraries_in_flutter
- no_logic_in_create_state
- prefer_const_constructors
- prefer_const_constructors_in_immutables
- prefer_const_declarations
- prefer_const_literals_to_create_immutables
- sized_box_for_whitespace
- use_full_hex_values_for_flutter_colors
- use_key_in_widget_constructors
也就是Dart的recommended規則增加了11項,如果開發者想要增加規則,只需要在analysis_option.yaml文件中的rules中,增加規則名稱,并設置為true。例如:
prefer_single_quotes: true
刪除規則
同樣也可以刪除默認的規則中的某些規則,或者讓他不起效,只需要在analysis_option.yaml文件中的rules中,增加規則名稱,并設置為false。例如:
avoid_print: false
將某些文件排除在代碼檢查之外
同樣我們可以將某些文件排除在代碼規則檢查之外,我們可以在analyzer中添加exclude,例如:
analyzer:
exclude:
- lib/client.dart
- lib/server/*.g.dart
- test/_data/**
APP的代碼規則實踐
在默認規則下,我們發現了不少代碼問題,特別是因為我們的代碼剛遷移到Flutter 2.0的空安全,其中不少和空安全的規則有關。在代碼的根目錄下運行,dart analyze,我們盡可以看到APP中的常見的違反代碼規則的地方:
不必要的冗余代碼:
創建類的實例不需要使用new(unnecessary_new)
除了防止被覆蓋,使用類的屬性時,不需要使用this來修飾
在對象不可能為null的情況下,不需要使用非空判斷(主要來源于空安全的轉換過程中,有些無用代碼未被刪除)
Dart 2.0的新規則的采用:
在函數中應該使用=將命名參數和他的默認值分開,而在Dart 2.12之前一直是使用冒號(:)
使用isEmpty來判斷集合中是否存在元素,而不是使用length
函數的集合類型的入參應該明確指出集合中的對象類型
在async函數中,調用返回Future的方法時,必須要在調用前明確指出,是await還是unawait
避免在forEach中使用簡寫函數字面量,而是應該使用for( in )
應該總是在函數中定義函數的返回類型
在剛開始制定代碼規范的時候,默認的代碼規范已經能滿足我們的基礎需求了。但是隨著開發的不斷深入,規則需要隨之而進行不斷的完善和改進,刪除很多并不必要的規則。制定代碼規范不是為了制定規范而規范,而是為了提高代碼質量和代碼的可維護性。規則制定完之后,當然就需要盡最大的努力保證規則的執行。目前我們也在考慮在CI中加入代碼規范的檢查。通過持續集成快速檢測,實時將結果反饋給代碼的對應負責人,降低規范落地的成本。代碼是研發團隊的核心資產,需要我們共同守護。
參考文獻:
https://dart.dev/tools#ides-and-editors
https://dart-lang.github.io/linter/lints/index.html