본문 바로가기
비전공자를 위한 Flutter/Flutter 심화과정

구글에서 사용하는 Flutter 코딩 컨벤션 flutter_lints 알아보기

by 밍잔 2022. 4. 19.

코딩 컨벤션이란 무엇인가요?

사람들과 함께 협업을 할 때 코딩의 규칙이 없으면 각자가 편한대로 코딩하게 됩니다. 그렇게 방치한 상태로 시간이 많이 흐르게 되면, 나중에 그 코드를 짠 당사자가 없으면 해석하기 어려운 지경에 이르게 되죠. 이런 일을 줄이기 위해 탄생한 게 코딩 컨벤션입니다. 코딩 컨벤션이란 누가 봐도 읽기 쉽고, 관리하기 편하도록 만든 코딩 스타일 규칙입니다. 아무도 사투리를 쓰지 않고, 표준어만 사용한다면 의사소통에 큰 지장이 없겠죠?

 


 

플러터에서는 어떤 코딩 컨벤션을 쓰나요?

플러터는 다트라는 언어를 사용합니다. Effective Dart라는 코딩 가이드라인이 있죠. 보통 여기서 제공하는 가이드라인을 회사나 팀에 따라 필요한 부분을 채택하여 사용합니다. 그러다보니 회사나 팀마다 코딩 스타일이 조금씩 다를 수 있습니다.

 

 

여러분께 권해드리는 코딩 컨벤션은 pedantic입니다. pedantic은 구글 내부에서 실제로 사용하고 있는 코딩 컨벤션이죠. 3년 전 이 컨벤션이 처음 나오고 1년 동안 업데이트 되었습니다. 2021년부터 pedantic패키지는 더이상 사용되지 않고, flutter_lints라는 패키지로 대체되었고, lints라는 패키지의 recommended 규칙이 포함되어 사용되고 있습니다. Dart Linter의 각 항목에 대한 설명은 아래 링크에서 확인하실 수 있습니다. 

 

 

Linter for Dart

Linter for Dart Lint Rules Using the Linter Supported Lint Rules This list is auto-generated from our sources. Rules are organized into familiar rule groups. errors - Possible coding errors. style - Matters of style, largely derived from the official Dart

dart-lang.github.io

 

기본적으로 Dart에서 사용할 가이드라인과 flutter_lints에서 사용된 항목만 추려서 알려드리도록 하겠습니다. (인스타그램 카드 뉴스로 편하게 볼 수 있도록 계획 중입니다.)

 

 

Effective Dart 

 

Effective Dart: Style

Formatting and naming rules for consistent, readable code.

dart.dev

- 클래스 이름은 UpperCamelCase 규칙을 따르세요.

- 라이브러리, 패키지, 디렉토리, 파일 이름은 lowercase_with_underscores 규칙을 따르세요.

- prefix 이름은 lowercase_with_underscores 규칙을 따르세요.

- 상수를 포함한 다른 식별자들은 lowerCamelCase 규칙을 따르세요.

- 두 문자어와 약어만 대문자로 표시하세요. (HTTPSFTP처럼 만들면 HTTPS+FTP인지 HTTP+SFTP인지 헷갈리게 됩니다.)

- 사용하지 않는 콜백 파라미터는 _로 할당하세요.

- 프라이빗 식별자가 아닌 식별자에는 언더스코어를 사용하지 마세요.

- 식별자에 prefix를 추가하지 마세요.

- import dart: 가 import package: 보다 상위에 위치하게 하세요.

- impot package: 가 의존성 import보다 상위에 위치하게 하세요.

- export는 가장 아래에 import와 한 줄 띄워 구분되도록 위치하게 하세요.

- import를 알파벳 순으로 정렬하세요.

- 아래 명령어를 실행하여 코드를 정렬시키세요.

dart format .

- 코드 한 줄에 80자를 넘지 않도록 하세요.

- 조건문 뒤 상태절은 {}로 감싸도록 하세요. (예외) else문이 없고 한 줄에 끝나는 경우 {}로 감싸지 않아도 됩니다.

 

 


 

flutter_lints.yaml

규칙 설명
- avoid_print 배포용 코드에 print를 사용하지 마세요.
- avoid_unnecessary_containers 아무 파라미터 없이 Container로 자식 위젯을 감싸지 마세요.
- avoid_web_libraries_in_flutter 웹용 라이브러리 사용은 피하세요. 
- no_logic_in_create_state createState 안에는 어떤 로직도 작성하지 마세요.
- prefer_const_constructors 되도록 const 생성자를 사용하세요.
- prefer_const_constructors_in_immutables @immutable 클래스에선 되도록 const 생성자를 사용하세요.
- prefer_const_declarations final 보다 const 선언을 우선시 하세요.
- prefer_const_literals_to_create_immutables @immutable 클래스에선 되도록 const 파라미터로 받으세요.
- sized_box_for_whitespace 여백을 만들기 위해서 SizedBox를 사용하세요.
- sort_child_properties_last 위젯의 child 프로퍼티는 가장 아래에 작성하세요.
- use_build_context_synchronously 비동기 작업에서 context를 사용하지 마세요.
- use_full_hex_values_for_flutter_colors 컬러를 지정할때 Color(0xFFFFFFFF)의 형식을 사용하세요.
- use_key_in_widget_constructors 위젯 생성자에 key를 사용하세요.

 


 

recommended.yaml

 

규칙 설명
- always_require_non_null_named_parameters 파라미터는 @required 어노테이션을 추가하여 null인 일이 없도록 하세요.
- annotate_overrides 오버라이드된 코드에는 주석을 작성하세요.
- avoid_function_literals_in_foreach_calls forEach는 사용하지 마세요. for-in 을 사용하세요
- avoid_init_to_null 변수를 null로 초기화하지 마세요.
- avoid_null_checks_in_equality_operators 조건문에서 (null == null) 으로 비교하는 일이 없도록 하세요.
- avoid_renaming_method_parameters 메소드를 오버라이드할 때 파라미터의 이름을 바꾸지 마세요.
- avoid_return_types_on_setters setter에서 타입을 반환하지 마세요.
- avoid_returning_null_for_void void 메소드에서 null을 반환하지 마세요.
- avoid_single_cascade_in_expression_statements 단순 표현문에서 .. 캐스케이드를 사용하지 마세요.
- constant_identifier_names 상수 이름은 lowerCamelCase 규칙을 따르세요.
- control_flow_in_finally try catch 문 마지막에 finally를 사용하지 마세요.
- empty_constructor_bodies 빈 객체를 생성하는 경우 {} 대신 ;를 사용하세요.
- empty_statements 빈 상태문을 만들지 마세요.
- exhaustive_cases enum 등을 switch문으로 비교하는 경우 모든 case를 작성하세요.
- implementation_imports 다른 패키지에 포함된 파일을 임포트하지 마세요.
- library_names 라이브러리 이름은 lowercase_with_underscores 규칙을 따르세요.
- library_prefixes 라이브러리에 prefix를 지정해야하는 경우 lowercase_with_underscores 규칙을 따르세요.
- library_private_types_in_public_api 공용 API에서 private 타입을 사용하지 마세요.
- no_leading_underscores_for_library_prefixes 라이브러리 prefix 문자를 언더스코어로 시작하지 마세요.
- no_leading_underscores_for_local_identifiers 함수 또는 블럭 내에 선언된 식별자 이름를 언더스코어로 시작하지 마세요.
- null_closures 클로저가 발생하게 되는 경우 null을 파라미터로 넘기지 마세요.
(클로저란? 같은 함수 본문을 가지지만 다른 변수를 갖는 식별자)
- overridden_fields 필드를 오버라이드 하지 마세요.
- package_names 패키지 이름은 lowercase_with_underscores 규칙을 따르세요.
- prefer_adjacent_string_concatenation 문자열을 합칠 때엔 +를 사용하지 않고 'AB''CD' 처럼 쓰세요.
- prefer_collection_literals 가능하면 List, Map로 지정하지 말고 컬렉션 리터럴을 사용하세요.
(리터럴이란? 그 자체로 값을 의미하는 것)
- prefer_conditional_assignment 조건문에서 null인지 체크하고 값을 할당할 때에는 ??= 연산자를 사용하세요.
- prefer_contains indexOf 대신에 contains를 사용하세요. (indexOf는 컬렉션이 읽기 힘든 변수를 가진 경우 성능저하를 일으킬 수 있어요.)
- prefer_equal_for_default_values 파라미터의 기본값을 설정할 때에는 : 대신 = 를 사용하세요.
- prefer_final_fields 가능하면 변수가 다시 할당되지 않도록 final을 사용하세요. (실수로 재할당되는 일을 방지하고, 컴파일러가 최적화 됩니다.)
- prefer_for_elements_to_map_fromIterable map의 키, 밸류 쌍을 처리해야하는 경우 for-in문을 사용하세요.
- prefer_function_declarations_over_variables 함수를 정의하는 경우 리터럴 대신 함수 선언을 사용하세요.
- prefer_if_null_operators null을 체크해서 값을 할당하는 경우 ?? 연산자를 사용하세요.
- prefer_initializing_formals 가능하면 초기화 형식을 사용하세요.
- prefer_inlined_adds 리스트는 add, addAll 함수를 쓰지말고 리터럴로 선언하세요.
- prefer_interpolation_to_compose_strings 문자열 안에 변수를 추가할 때 '$변수'를 사용하세요.
- prefer_is_not_operator 객체가 지정된 타입이 아닌지 확인할 때 is! 를 사용하세요.
- prefer_null_aware_operators null 체크 후 프로퍼티에 접근할 때 ?. 연산자를 사용하세요.
- prefer_spread_collections 리스트는 가능하면 ..addAll()가 아니라 스프레드 [, ...]를 사용하세요.
- prefer_void_to_null void 함수를 실행할 때 null을 반환하지 않도록 하세요.
- recursive_getters 자신의 값을 반환하는 변수 getter는 _변수의 값을 얻도록 하세요.
- slash_for_doc_comments 문서용 주석을 남길 때에는 /// 를 사용하세요.
- type_init_formals 초기화할 때 필드의 타입을 다시 선언하지 마세요.
- unnecessary_brace_in_string_interps 문자열 안에서 변수를 사용할 때 불필요한 경우 {}로 감싸지 마세요.
- unnecessary_const 리터럴 선언에서 중복 const 선언을 하지 마세요.
- unnecessary_constructor_name 불필요하게 .new 생성자를 사용하지 마세요.
- unnecessary_getters_setters 단순히 안전을 위해서 필드를 getter setter로 랩핑하지 마세요.
- unnecessary_late 정적 변수 또는 탑 레벨에 있는 변수에 late를 지정하지 마세요.
- unnecessary_new 인스턴스 생성할 때 new 키워드를 사용하지 마세요.
- unnecessary_null_aware_assignments 변수가 null인지 체크하고 나서 다시 null을 할당하지 마세요.
- unnecessary_null_in_if_null_operators null 인지 체크하는 ?? 연산자에 null을 대입하지 마세요.
- unnecessary_nullable_for_final_variable_declarations non-nullable 타입을 사용하세요.
- unnecessary_string_escapes 따옴표, 쌍따옴표 때문에 불필요하게 escape하지 마세요.
- unnecessary_string_interpolations 문자 인스턴스에 문자를 할당할 때 불필요하게 문자열을 '$변수'로 할당하지 마세요.
- unnecessary_this 값이 변경될 필드와 새로 할당할 값의 필드 이름이 일치하지 않는 경우 불필요하게 this. 를 사용하지 마세요.
- use_function_type_syntax_for_parameters 함수를 파라미터로 넘길 때 일반 함수 구문으로 넘기세요.
- use_rethrow_when_possible catch 문 안에 예외를 다시 발생시키기 위해 rethrow를 사용하세요.

 


 

코딩 컨벤션은 어떻게 쓰나요?

Linter, 린터라고 부르는 도구를 이용해서 코딩 컨벤션을 지키도록 합니다. Linter, 린터란 코딩 컨벤션을 잘 지켰는지 체크하고 에러나 경고를 나타내주는 도구입니다. 사용 방법은 린터에게 우리가 지킬 코딩 가이드라인을 지정시켜놓으면 됩니다. 그러면 우리가 코딩을 할 때, 프로그램이 빌드 또는 실행 중이지 않아도 린터가 IDE(코딩을 위한 텍스트 편집기. Visual Studio Code 등)에서 자동으로 오류를 보여줍니다. 가이드라인을 주입하여 나타나는 린터가 보여주는 에러는 프로그램을 빌드할 때 아무런 영향도 끼치지 않죠. 코딩 가이드라인을 지키도록 개발자를 유도해주는 역할을 합니다. 아래 링크는 pedantic 패키지가 더이상 사용되지 않고, flutter_lints라는 새로운 이름으로 만들어진 코딩 컨벤션 패키지입니다.

 

 

flutter_lints | Dart Package

Recommended lints for Flutter apps, packages, and plugins to encourage good coding practices.

pub.dev

 

설치 및 사용 방법은 아래와 같습니다. 

 

개발 의존성 도구에 flutter_lints를 추가하여 설치하고, 아래의 명령어를 실행시켜 개발도구에 flutter_lints를 추가합니다.

 

flutter pub add flutter_lints --dev

 

프로젝트의 루트 디렉토리에 analysis_options.yaml 파일을 생성하고 아래와 같이 작성합니다.

 

include: package:flutter_lints/flutter.yaml

linter:
  rules:

 

여기까지 하면 여러분의 코드에 못 보던 경고나 오류가 생긴 것을 확인하실 수 있습니다.

 

댓글