한국 날짜로 5월 15일 Dart 3.4가 업데이트 되었고, 구글의 플러터와 다트의 프로덕트 메니저인 Michael Thomsen이 Medium에 다트 3.4 업데이트 공지를 올렸습니다. 번역 글을 작성하며 다트 3.4 업데이트 스펙을 살펴보기 위해 글을 작성합니다.
다트 3.4가 한국 시간으로 5월 15일 추시되었습니다. 이번 릴리즈에 대한 자세한 내용은 Landing Flutter 3.22 and Dart 3.4 at Google I/O 2024에서 살펴볼 수 있습니다. 이 글에서는 웹어셈블리와 다트의 주요 로드맵 이었던 매크로에 대해 자세히 소개하겠습니다.
WebAssembly Updates
Flutter 3.22 버전을 배포하며 플러터 웹앱에 WebAssembly(Wasm)을 완벽하게 지원하게 되었습니다. 이는 다트 및 플러터 전반에 걸쳐 다년간의 노력을 통해 이루어졌습니다. 그동안의 개발 과정을 지켜봤다면 점진적으로 개발되는 모습을 보셨을 것입니다.
- WasmGC에 대한 제안
- 새로운 다트 컴파일러를 추가해 WasmGC 코드 생성
- Wasm을 지원하기 위해 웹과 자바스크립트 Interop 개선
(참고 : 다트 웹 플랫폼은 dart:js_interop을 통해 브러우저 API나 자바스크립트나 다른 라이브러리와의 통신을 지원합니다.)
앞으로도 WebAssembly에 지속적으로 투자할 것입니다. 다음 작업에서는 다트에서 Wasm을 몇 가지 누락된 기능(지연 로딩 등)을 포함해 완벽하게 지원할 예정입니다. 다트에서 Wasm 컴파일을 위한 End-to-End 도구는 아직 개발중이지만 임시로 제공하는 도구를 사용해볼 수 있습니다. 추후에는 Wasmtime이나 Wasmer와 같은 표준 런타임과 같은 JS 환경 외부의 다트에서도 Wasm을 지원하려고 합니다.
(참고 : Wasmtime이나 Wasmer는 Wasm 코드를 실행하기 위한 런타임 환경으로 Wasm 코드를 실행하기 위해서는 Wasmtime이나 Wasmer와 같은 런타임이 필요합니다. Wasm 런타임 환경은 기존 Javascript 런타임과 대비되는데, Wasm 런타임은 Wasm 코드를 실행하고, Javascript 런티임 환경보다 빠른 실행 속도를 제공합니다. Javascript, Typescript 뿐만아니라 C/C++, Rust, Go 등 다양한 프로그래밍언어를 Wasm 컴파일러를 통해 Wasm 코드로 변환할 수 있는데, 보안이나 메모리 등에서도 이점이 있습니다.)
Dart macros: Rasing the development abstraction level
다트팀은 매크로 시스템을 설계하는데 많은 시간(many years)을 투자해왔습니다. 매크로는 코드 생성과 같은 메타 프로그래밍을 가능하게하여 다트 개발 경험을 개선합니다. 매크로는 개발자에게 생산성과 효율성, 성능 개선 등을 위해 다트 언어에 포함되었습니다. 이제 preview로 제공할 준비가 되었습니다.
다트 개발자들의 오랜 고충 중 하나는 사소하고 지루한 json의 직렬화와 역직렬화 입니다. 성능상의 이유로 런타임 리플랙션을 지원하지 않는 다트에서 재사용 가능하고 효과적인 솔루션을 만드는건 어려운 과제였습니다. 이에 대한 대안으로 JsonSerializable과 같은 코드 제너레이터에 의존해왔습니다. 하지만 코드 제너레이터와 같은 도구는 컴파일 이전에 실행 되야 하기 때문에 개발 환경을 복잡하게 만드는 경향이 있습니다.
JSON 직렬화 및 역직렬화를 위한 새로운 접근 방식인 JsonCodable 매크로의 Preview 버전을 공개합니다. 매크로는 컴파일 시 다른 코드를 Introspecting하여 코드를 생성합니다. 아래 예제는 JsonCodable 매크로를 Vehicle 클래스에 적용한 예제입니다.
@JsonCodable()
class Vehicle {
final String description;
final int wheels;
Vehicle(this.description, this.wheels);
}
void main() {
final jsonString = Vehicle('bicycle', 2).toJson();
print('Vehicle serialized: $jsonString');
}
JsonCodable을 통한 직렬화와 역직렬화는 어떻게 동작하는걸까요? toJson 메서드나 toJson의 친구인 fromJson 생성자는 어디에서 왔을까요? 이 예제는 개발 경험을 개선하기 위해 만들어진 매크로의 실험적인 구현의 결과입니다. 다트 컴파일러는 @JsonCodable() 어노테이션을 발견하면 JsonCodable 매크로의 정의를 실시간으로 실행을 시작합니다. 그러면 매크로는 아래와 같이 동작합니다.
- 기존 클래스에 새로운 코드를 추가하기 위한 증강 클래스(Augmentation Class)를 생성합니다.
- 개발자가 작성한 Vehicle 클래스를 바탕으로 증강 클래스가 description과 wheels라는 두 개의 필드가 있는지 확인합니다.
- 증강 클래스에 toJson 메서드 시그니쳐를 추가합니다.
- toJson 메서드에서 description과 wheels 필드에 대한 json 직렬화를 처리 로직을 채웁니다.
이 모든 것이 순식간에 이루어집니다. 아래 실행 과정에서 볼 수 있듯이 핫 리로드와 같은 기존 개발 워크플로우를 지원합니다.
Long term macro goals
궁극적인 목표는 오픈소스 커뮤니티에서 다양한 매크로가 만들어지도록 하는 것입니다. 다양한 매크로는 다트 프로그래밍의 추상화 수준을 높일 것 입니다. 예를 들어 다트 깃헙에서 가장 높은 따봉 리액션을 획득한 Add data classes 이슈를 생각해 봅시다. data 클래스를 추가하는 것을 검토했지만 표준이 되기 위해 무엇을 지원해야 하는지에 대한 의견이 상당히 다양했습니다. 데이터 클래스는 필드가 불변이어야 할까요? 동등성을 지원해야 할까요? 해시코드나 toString도 지원해야 할까요? 이런 다양한 의견보다는 매크로 시스템을 지원하는게 더 나은 접근 방식이라는 결론을 내렸습니다. 오픈소스 커뮤니티에서는 매크로를 통해 추상화 수준으로 올리고, 확장 가능한 다양한 실험이 가능해집니다.
이러한 매크로 시스템을 설계하고 구현하는 것은 상당한 작업이었습니다. 코드 작성, 분석, 핫리로드와 같은 다트 핵심적인 기능에 영향을 주지 않기 위해 매크로를 단계적인 접근 방식을 취하고 있습니다.
- 이번 릴리즈에서 개발자가 매크로를 사용하는 개발 환경에 익숙해질 수 있도록 JsonCodable을 Preview로 제공합니다.
- JsonCodable이 이번 릴리즈에서 순조롭게 출시되면, 이후 릴리즈에서 안정적인 버젼으로 업그레이드할 수 있을것을 기대합니다.
- 이와 동시에 기본 매크로 시스템의 설계와 구현을 완료하기 노력하고 있습니다. 성능과 안정성에 확신을 갖게되면 궁극적으로는 다트 개발자 커뮤니티가 자체 매크로를 정의할 수 있도록 할 것 입니다.
이 단계를 완료하려면 아직 많은 작업이 남아 있습니다. 그 동안에는 문서를 읽고 다트 매크로 시스템에 대해 자세히 알아보고 JsonCodable 매크로의 Preview 버젼을 사용해보세요.
Other improvements
항상 그렇지만 이번 릴리즈에서도 가능한 최상의 다트 버젼을 제공하기 위해 continuous development한 내용을 포함하고 있습니다. 이번 릴리즈에 아래와 같은 개선이 이루어졌습니다.
- 50%의 Analyzer Code Completion 이슈 대응
- 조건식, if-null 표현식, 스위치 표현식이 대한 언어 스펙에 맞도록 개선
- 다트 VM의 기술 부채를 없에기 위해 dart:cli 라이브러리에서 불완전하고 인관되지 않은 기능 제거
- dart:js_interop 라이브러리를 개선하기 위해 몇 가지 미흡한 부분 해결
Changelog에서 전체 변경 로그를 확인할 수 있습니다. 이번 릴리즈를 위한 개발팀의 노력에 대한 보다 자세한 이야기는 다트와 플러터팀의 블로그 포스팅을 읽어보세요.
번역을 마친 후
Announcing Dart 3.4 글을 번역한 후 JsonCodable에 대한 분석 글을 작성하며 매크로에 대해 학습중입니다. JsonCodable 매크로의 구현을 직접 살펴보며 매크로를 직접 만들기 위한 지식을 쌓는 중입니다. 처음 JsonCodable 매크로의 구현체를 봤을 때 복잡해보이기만 하던 코드가 의외로 단순한 형태로 구현되어 있음을 알 수 있었습니다. 총 4편으로 작성될 매크로에 대한 포스팅은 발행하는데로 하단에 링크로 남기겠습니다.