起源
做为跨平台的移动端解决方案,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