Dart 튜토리얼 35편: Dart 언어 진화와 변경점(Language evolution·Breaking changes)
요약
핵심 요지
- 문제 정의: SDK/언어 버전이 오르면 기능은 좋아지지만, 기존 코드가 깨질 수 있고 경고가 늘 수 있다.
- 핵심 주장: 변화에 대응하려면 “언어 기능 변화(진화)와 깨지는 변경(브레이킹/폐기/제거)을 분리해서 추적”하고, SDK constraint1와 언어 버전(language versioned) 개념을 기준으로 적용 범위를 판단해야 한다.
- 주요 근거:
pubspec.yaml의 SDK constraint 예시, 변경 유형(Unversioned/Language versioned/Deprecations/Removed/Experimental) 분류가 제시된다. - 실무 기준: 업데이트 전 체크(변경 목록 확인) → 업데이트 후 정리(
dart analyze,dart fix) → 테스트/빌드 검증 순서로 대응한다.
문서가 설명하는 범위
- Dart 언어 기능이 릴리즈별로 어떻게 추가/변경되는지의 요약
- 변경 유형(언어 버전 유지 여부, 폐기/제거, 실험 기능)의 분류 기준
- 코드가 깨질 수 있는 변경에 대응하는 실무 루틴(분석/자동 수정/제약 확인)
읽는 시간: 13분 | 난이도: 초급
참고 자료
문제 상황
버전을 올리면 두 가지가 동시에 일어납니다.
좋은 변화(새 기능/개선)와, 부담되는 변화(깨짐/경고/제약 변화)입니다.
여기서 가장 흔한 실패는 “무작정 올렸다가” 프로젝트가 깨지고, 왜 깨졌는지 모르고 시간을 쓰는 것입니다.
그래서 변화는 “분류 기준”과 “대응 루틴”으로 다뤄야 합니다.
해결 방법
단계 1: pubspec.yaml의 SDK constraint로 “사용 가능한 기능 범위”를 고정한다
Why
NOTE언어 기능은 “언제부터 지원되는지”가 정해져 있습니다.
SDK constraint를 명확히 하면, 기능 사용 가능 여부와 업그레이드 기준이 함께 정리됩니다.
What
NOTE특정 언어 기능을 쓰려면, 그 기능이 도입된 버전 이상으로 SDK constraint를 잡아야 한다는 예시가 제시됩니다.
예를 들어 null safety는 2.12에 도입되었고, 그에 맞춰 lower bound를 올리는 예시가 제시됩니다.
How
TIP예시는 다음과 같습니다.
environment:sdk: '>=2.12.0 <3.0.0'
Watch out
WARNINGSDK constraint를 올리는 것은 “패키지/앱 전체”에 영향을 줍니다.
따라서 의존성 그래프와 CI 환경에서도 같은 SDK를 쓰는지 함께 확인해야 합니다.
결론: SDK constraint를 명확히 두면, 기능 사용 가능 범위와 업그레이드 기준이 같이 고정됩니다.
단계 2: 변경 유형을 구분해서 “깨짐의 범위”를 판단한다
Why
NOTE모든 변경이 같은 위험도를 가지지 않습니다.
변경 유형을 구분하면 “지금 바로 깨지는지/나중에 깨질지/일부 코드만 깨질지”를 빠르게 판단할 수 있습니다.
What
NOTE변경 유형은 다음처럼 구분되는 흐름이 제시됩니다.
Unversioned(즉시 깨질 수 있음), Language versioned(언어 버전 올릴 때 적용), Deprecations(경고 후 나중에 제거), Removed(이미 제거), Experimental(릴리즈에 포함되지만 불안정).
How
TIP업그레이드 전에 “내 프로젝트에 해당되는 변경만” 추려서 체크리스트로 만듭니다.
예를 들어 Wasm 타깃을 쓰거나 계획이 있다면, JS interop 관련 제거/제약 변경을 최우선으로 체크하는 식입니다.
Watch out
WARNINGLanguage versioned 변경은 “코드가 바로 깨지지 않을 수도” 있습니다.
하지만 언어 버전을 올리는 순간 적용될 수 있으므로, “안 깨지니까 괜찮다”로 결론 내리면 나중에 더 큰 비용이 생길 수 있습니다.
결론: 변경 유형을 먼저 분류하면, 대응의 우선순위와 범위를 더 정확히 정할 수 있습니다.
단계 3: 업데이트 후에는 dart analyze와 dart fix로 “기계가 할 일”을 먼저 처리한다
Why
NOTE버전 업데이트 후에는 경고/에러가 늘 수 있습니다.
이때 사람이 하나씩 고치기 전에, 자동화 도구로 처리 가능한 부분을 먼저 줄여야 합니다.
What
NOTE분석은
dart analyze2, 자동 수정은dart fix3로 수행하는 흐름이 제시됩니다.
또한dart fix는 오래된 API 사용을 새 방식으로 옮기는 데도 사용된다는 흐름이 제시됩니다.
How
TIP루틴 예시:
Terminal window $ dart analyze$ dart fix --dry-run$ dart fix --apply$ dart analyze
Watch out
WARNING자동 수정은 “규칙이 켜져 있어야” 적용 범위가 늘 수 있다는 설명이 있습니다.
따라서 분석 옵션(린트/플러그인)을 함께 관리해야 자동화의 효과가 커집니다.
결론: 업데이트 후에는 분석/자동 수정을 먼저 돌려서, 사람이 판단할 이슈만 남기는 것이 효율적입니다.
단계 4: 릴리즈별 진화를 “정기적으로” 확인해, 변화에 익숙해진다
Why
NOTE한 번에 큰 버전 점프를 하면, 변경점이 너무 많아져서 대응이 어려워집니다.
정기적으로 변화(언어 기능/도구 변화)를 확인하면 부담이 줄어듭니다.
What
NOTE언어 진화 페이지는 릴리즈별로 새 기능/변화를 요약해 보여주는 형태로 구성되어 있습니다.
예를 들어 dot shorthands 같은 기능이 릴리즈 단위로 소개됩니다.
How
TIP릴리즈마다 “우리 코드 스타일/도구 체인”에 영향을 주는 항목만 골라서 팀 규칙에 반영합니다.
예: 포맷터 변화, 분석기 변화, interop 제약 변화, 빌드 도구 변화.
Watch out
WARNING릴리즈 노트/변경 목록은 “영향 범위가 넓은 도구 변경”을 포함할 수 있습니다.
따라서 언어 기능만 보지 말고, Tools 섹션까지 함께 확인하는 습관이 필요합니다.
결론: 변화는 “정기적으로 작게” 흡수하는 것이 가장 안전한 업데이트 전략입니다.
Footnotes
공유
이 글이 도움이 되었다면 다른 사람과 공유해주세요!