Flutter 안티패턴을 잡아주는 린트 규칙 모음. 설정 없이, 추가만 하면 바로 동작합니다.
# pubspec.yaml
dev_dependencies:
custom_lint: ^0.6.4
flint:
git:
url: https://github.com/suojae/flint.git# analysis_options.yaml
analyzer:
plugins:
- custom_lint| 규칙 | 설명 |
|---|---|
avoid_image_opacity |
Image를 Opacity로 감싸지 마세요. color + colorBlendMode를 사용하세요. |
avoid_hardcoded_border_radius |
build 메서드에서 BorderRadius.circular(12) 하드코딩 금지. 디자인 토큰(예: AppRadius.medium)을 사용하세요. |
avoid_hardcoded_color |
build 메서드에서 Color(0xFF...) 하드코딩 금지. colorScheme을 사용하세요. |
avoid_hardcoded_elevation |
build 메서드에서 elevation: 4 하드코딩 금지. 디자인 토큰(예: AppElevation.medium)을 사용하세요. |
avoid_hardcoded_font_size |
build 메서드에서 fontSize: 14 하드코딩 금지. 타이포그래피 토큰(예: AppTypo.body)을 사용하세요. |
avoid_hardcoded_icon_size |
build 메서드에서 Icon(size: 24) 하드코딩 금지. 디자인 토큰(예: AppIconSize.md)을 사용하세요. |
avoid_hardcoded_spacing |
build 메서드에서 EdgeInsets.all(16) 하드코딩 금지. 디자인 토큰(예: AppSpacing.md)을 사용하세요. |
avoid_controller_in_build |
build() 안에서 TextEditingController/ScrollController/FocusNode 등을 생성하지 마세요. |
avoid_raw_go_router_navigation |
context.go('/x'), router.pushNamed('foo') 같은 raw go_router 호출 대신 typed route API를 사용하세요. |
avoid_side_effect_in_build |
build() 안에서 Navigator.push, showDialog, bloc.add(), addPostFrameCallback() 같은 side effect를 실행하거나 예약하지 마세요. |
avoid_visibility_widget |
Visibility/Offstage로 위젯을 숨기지 마세요. 조건부 렌더링을 사용하세요. |
avoid_shrink_wrap_in_list |
ListView/GridView에서 shrinkWrap: true 금지. Sliver를 사용하세요. |
prefer_specific_media_query_methods |
MediaQuery.of(context).size, .padding, .devicePixelRatio 대신 sizeOf, paddingOf, devicePixelRatioOf 같은 전용 접근자를 사용하세요. |
enforce_dispose_owned_fields |
State가 직접 만든 controller/node는 dispose()에서 반드시 정리하세요. |
enforce_design_token_layer_import |
디자인 토큰 계층(constants → primitive → semantic → component) import 방향을 강제합니다. |
enforce_layer_dependency_direction |
features/<feature>/{domain,data,presentation} 레이어 의존 방향을 강제합니다. |
설치 후 IDE에서 자동으로 경고가 표시됩니다. CLI로도 실행 가능합니다:
dart run custom_lint# analysis_options.yaml
custom_lint:
rules:
- avoid_hardcoded_color: falseMIT