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#

WARNING

SDK constraint를 올리는 것은 “패키지/앱 전체”에 영향을 줍니다.
따라서 의존성 그래프와 CI 환경에서도 같은 SDK를 쓰는지 함께 확인해야 합니다.

결론: SDK constraint를 명확히 두면, 기능 사용 가능 범위와 업그레이드 기준이 같이 고정됩니다.


단계 2: 변경 유형을 구분해서 “깨짐의 범위”를 판단한다#

Why#

NOTE

모든 변경이 같은 위험도를 가지지 않습니다.
변경 유형을 구분하면 “지금 바로 깨지는지/나중에 깨질지/일부 코드만 깨질지”를 빠르게 판단할 수 있습니다.

What#

NOTE

변경 유형은 다음처럼 구분되는 흐름이 제시됩니다.
Unversioned(즉시 깨질 수 있음), Language versioned(언어 버전 올릴 때 적용), Deprecations(경고 후 나중에 제거), Removed(이미 제거), Experimental(릴리즈에 포함되지만 불안정).

How#

TIP

업그레이드 전에 “내 프로젝트에 해당되는 변경만” 추려서 체크리스트로 만듭니다.
예를 들어 Wasm 타깃을 쓰거나 계획이 있다면, JS interop 관련 제거/제약 변경을 최우선으로 체크하는 식입니다.

Watch out#

WARNING

Language versioned 변경은 “코드가 바로 깨지지 않을 수도” 있습니다.
하지만 언어 버전을 올리는 순간 적용될 수 있으므로, “안 깨지니까 괜찮다”로 결론 내리면 나중에 더 큰 비용이 생길 수 있습니다.

결론: 변경 유형을 먼저 분류하면, 대응의 우선순위와 범위를 더 정확히 정할 수 있습니다.


단계 3: 업데이트 후에는 dart analyzedart 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#

  1. SDK constraint(SDK 제약): pubspec.yaml에서 Dart SDK 버전 범위를 제한하는 설정이다.

  2. dart analyze(dart analyze): 코드 정적 분석을 실행하는 명령이다.

  3. dart fix(dart fix): 분석 이슈에 대한 자동 수정(quick fix)을 적용하는 명령이다.

공유

이 글이 도움이 되었다면 다른 사람과 공유해주세요!

Dart 튜토리얼 35편: Dart 언어 진화와 변경점(Language evolution·Breaking changes)
https://moodturnpost.net/posts/dart/dart-evolution-breaking-changes/
작성자
Moodturn
게시일
2026-01-04
Moodturn

목차