언어 버전 관리
언어 버전 관리 (Language versioning)
Dart의 언어 버전 관리가 언어의 진화를 어떻게 가능하게 하는지, 프로젝트와 그 라이브러리의 언어 버전을 어떻게 설정하는지 살펴볼게요.
출처: Dart 공식 문서
본문
개요 (Overview)
하나의 Dart SDK가 동시에 여러 버전의 Dart 언어를 지원할 수 있어요. 컴파일러가 코드가 대상으로 하는 버전을 결정하고, 그 버전에 따라 코드를 해석해요.
언어 버전 관리는 Dart가 null safety 같은 호환되지 않는 기능을 도입하는 드문 경우에 중요해져요. Dart가 파괴적 변경(breaking change)을 도입하면, 컴파일되던 코드가 더 이상 컴파일되지 않을 수 있어요. 언어 버전 관리는 각 라이브러리의 언어 버전을 설정해 호환성을 유지할 수 있게 해줘요.
null safety의 경우, Dart SDK 2.12~2.19는 코드를 null safety를 사용하도록 선택적으로 업데이트할 수 있게 했어요. Dart는 언어 버전 관리를 사용해 non-null-safe 코드가 null-safe 코드와 나란히 실행되도록 허용해요. 이 결정 덕분에 non-null-safe에서 null-safe 코드로의 마이그레이션이 가능해졌어요. 앱이나 패키지가 호환되지 않는 기능을 가진 새 언어 버전으로 마이그레이션하는 방법의 예시를 보려면, 대규모 Dart 프로젝트의 점진적 null safety 마이그레이션 문서를 확인해 보세요.
각 패키지의 기본 언어 버전은 pubspec.yaml 파일의 SDK 제약의 하한(lower bound) 과 같아요.
예시: pubspec.yaml 파일의 다음 항목은 이 패키지가 기본적으로 Dart 2.18 언어 버전을 사용함을 나타내요.
environment:
sdk: '>=2.18.0 <3.0.0'
Dart 팀이 이 버전 방식을 어떻게, 왜 개발했는지 배우려면 언어 버전 관리 명세를 확인해 보세요.
언어 버전 번호 (Language version numbers)
Dart는 언어 버전을 마침표로 구분된 두 숫자로 표기해요. 메이저 버전 번호와 마이너 버전 번호로 읽어요. 마이너 버전 번호는 파괴적 변경을 도입할 수 있어요.
Dart 릴리스는 언어 버전에 패치 번호를 덧붙일 수 있어요. 패치는 버그 수정 외에는 언어를 바꾸지 않아야 해요. 예를 들어 Dart 2.18.3은 Dart 2.18 SDK 언어 버전의 최신 릴리스 역할을 해요.
각 Dart SDK 릴리스는 자신의 언어 버전과, 같은 메이저 버전 번호 안의 모든 이전 버전을 지원해요. 즉 Dart SDK 2.18.3은 언어 버전 2.0부터 2.18까지(포함)를 지원하지만, Dart 1.x는 지원하지 않아요.
SDK 버전에서 언어 버전을 파생한다는 것은 다음을 의미해요.
- SDK의 마이너 버전이 출시될 때마다 새 언어 버전이 등장해요. 실제로 이런 언어 버전 중 상당수는 이전 버전과 매우 비슷하게 동작하며 서로 완전히 호환돼요. 예: Dart 2.9 언어는 Dart 2.8 언어와 거의 같게 동작해요.
- SDK의 패치 릴리스가 출시될 때는 새 언어 기능을 도입할 수 없어요. 예: 2.18.3 릴리스는 여전히 언어 버전 2.18이에요. 2.18.2, 2.18.1, 2.18.0과 호환을 유지해야 해요.
라이브러리별 언어 버전 선택 (Per-library language version selection)
기본적으로 패키지의 모든 Dart 파일은 같은 언어 버전을 사용해요. Dart는 pubspec.yaml 파일에 지정된 SDK 제약의 하한을 기본 언어 버전으로 식별해요. 때로는 Dart 파일이 더 오래된 언어 버전을 사용해야 할 수 있어요. 예를 들어 패키지의 모든 파일을 동시에 null safety로 마이그레이션하지 못할 수 있어요.
Dart는 라이브러리별 언어 버전 선택을 지원해요. 패키지의 나머지와 다른 언어 버전을 선택하려면, Dart 라이브러리가 다음 형식의 주석을 포함해야 해요.
// @dart = <major>.<minor>
예를 들면 이렇게요.
// Description of what's in this file.
// @dart = 2.17
import 'dart:math';
// ...
@dart 문자열은 // 주석( ///나 /*가 아닌) 안에 있어야 하고, 파일의 어떤 Dart 코드보다 앞에 나타나야 해요. 공백(탭과 띄어쓰기)은 중요하지 않지만, @dart와 버전 문자열 안에서는 예외예요. 앞선 예시에서 보듯이 @dart 주석 앞에 다른 주석이 올 수 있어요.
언어 버전에 따른 변경 (Language-versioned changes)
언어 버전 관리는 Dart와 그 도구가 시간이 지나며 진화하도록 도와줘요. 문법과 의미론의 잠재적 파괴적 언어 변경 외에도, 새 기능과 도구 변경이 언어 버전에 따라 제한될 수 있어요. 예를 들어 dart format은 포맷하는 라이브러리의 언어 버전에 따라 Dart 코드를 다르게 포맷할 수 있어요.
각 언어 버전이 도입한 변경을 찾으려면 필터 가능한 Dart 변경 로그를 참조할 수 있어요. 각 언어 버전과 그 기능에 대한 구체적인 세부 사항을 배우려면 언어 문서와 언어 명세를 확인해 보세요.
팁
논의·설계·구현 중인 새 Dart 기능과 변경을 검토하려면 GitHub의 Dart language funnel 프로젝트를 확인해 보세요.
더 알아보기
- Dart 변경 로그 — 각 언어 버전의 변경 사항
- 언어 문서 — 언어 기능별 문서
- 언어 명세 — 권위 있는 언어 규칙