본 문서는 Fluter Example의 내용을 원저작자의 동의하에 번역한것 입니다.
원 저작자 Eric Windmill에게 감사를 전합니다.
이해하는데 불필요한 문장은 과감하게 버렸습니다. 오 번역에 대해서 의견 주시면 적극 반영 하겠습니다.

Flutter란?

Flutter는 모든 사람이 아름다운 모바일 앱을 개발 할 수 있도록 지원하는 모바일 SDK이다.
여러분이 웹개발자 이든 native 모바일 개발자 이든 관계없이 프레임워크 (역자주: android, ios, React native, Vue native…)을 사용 하지 않고 친숙하고 단순한 방식으로 모바일 앱을 보다 쉽게 만 들 수 있다.

이글을 쓰는 시점에서 Google AdWordsAlibaba 모두 플러터를 사용하고 있다.
플러터 웹사이트의 showcase 페이지에서 플러터의 사용예를 볼 수 있다.

요즘 플러터에 대해 말이 많다. 내가 종종 봤던 질문은 "Flutter랑 React Native 중에 어떤걸 사용해야 하냐?" 이다.
모든 프로그래밍이 다 그렇지만 여러분이 무언가 하고자 하면 그것에는 trade-off(이율 배반)가 따르기 마련이다.

나는 여러분에게 플러터가 모바일 앱 개발을 위한 최선의 선택이라는 것을 확신 시키기 위해 노력할 것이다.

나는 플러터가 다른 cross platform framework보다 뛰어나다고 믿으며 아마 native 개발보다 나을것이다. ( - 약간의 설명이 필요하긴 함. )

그전에 Dart 프로그래밍 언어 부터 시작해서 플러터가 무엇인지에 대해 빠르게 살펴 보겠다.

Dart란?

Dart는 구글에서 만든 프로그래밍 언어로 플러터를 작성하는데 사용됐다.
다트는 구글이 server sidefront-end코드를 작성하는데 Javascript 보다 더 나은 언어를 원했기에 만들어 졌다.

내가 알기로는, 자바스크립트의 가장 큰 문제는 승인을 위한 거대 위원회와 이를 구현하기 위한 여러 브라우저 공급업체에 의존하고 있기 때문에 새로운 기능 업데이트가 느리다는 것이다.

구글은 자바스크립트를 직접 사용할지 말지에 대한 일련의 결정 후에 의미적으로 자바스크립트와 맞는 언어를 만들기로 결정했다. 다시 말하자면 다트에서 작성되는 모든것은 자바스크립트로 컴파일 할 수 있으며 이것이 구글이 Java를 사용하지 않고 새로운 언어를 개발한 이유이다. - 이것은 큰 의미를 갖는다.

링크는 2010년 구글에서 유출된 이메일 체인 이다. 그들이 자바스크립트에 대해 뭔가 해야 한다는걸 결정한 것은 예수께 이르는 순간 이다.(역자주: 예수께 이르다는것은 무엇으로 부터 구원을 받은~ 으로 이해했음)

하지만 좋은 소식이 있다. 다트는 safe 언어를 배우는 데 탁월하다. 구글은 다트로 어떤 혁신적인것을 만들기 위해 시작하지 않았다. 그들은 단순하고 생산적이며 자바스크립트로 컴파일 될 수 있는 언어를 만들고자 했다.

구문에는 특별히 흥미로운것도 없으며 여러분을 혼란스럽게 할 특별한 연산자도 없다.
다트(자바스크립트와는 달리)에는 truefalse를 한 가지 방법으로만 표현한다.

자바스크립트에서 다음은 true로 인식된다.

1
if (3) { ... }

다트에선 위 처럼 하면 프로그램이 엉망이 될것이다. 다트의 핵심은 생산적이고 예측 가능하며 간단한 언어라는 것이다. 이것은 중요하다, 왜냐면 플러터에서 앱을 작성하는것은 단순히 다트를 작성하는 것이기 때문이다. 플러터는 하부에 다트 라이브러리 클래스들이 있다. markup 언어와 관련됐거나 JSX스타일의 하이브리드 언어는 없다. 모든 프론트 엔드 코드는 다트로 작성된다. No HTML, No CSS.

플러터가 다트를 사용하는 이유는?

만약 여러분이 다른 기술배경을 사용해봤다면 아마도 플러터가 자바스크립트가 아니라 다트를 사용한다는 사실에 대해 불평했을 것이다. (개발자들은 믿거나 말거나 독단적이다.)
그리고 이 선택에 회의적인 이유는 있다. 다트가 오늘날 가장 많이 사용되는 25개 언어에 포함되지 않는 인기 없는 언어라는 것이다. “뭐라구요? 구글이 자사 언어라서 사용했다구요?” 나는 그것도 맞는 소리라고 생각하지만 실용적인 이유도 있다.

  • 다트는 JIT(Just In Time)컴파일과 AOT(Ahead Of Time)컴파일을 모두 지원한다.
    • AOT컴파일러는 다트코드를 효율적인 native 코드로 바꾼다. 이것은 플러터를 빠르게 만들지만,(사용자와 개발자에게 승리) 거의 모든 프레임워크가 다트로 작성되었음을 의미 한다. 여러분 즉 개발자가 모든 것을 커스터마이징한다는 것이다.
    • 다트의 옵션인 JIT컴파일은 hot-reloading을 가능케 한다. 빠른 개발과 반복은 플러터 사용 즐거움의 핵심이다. 텍스트 편집기에 코드를 저장하면 시뮬레이터상의 앱이 1초 이내에 업데이트 된다.
  • 다트는 객체 지향이다. 이것은 다트만으로 시각적 사용자 경험(UX)을 쉽게 작성 할 수 있게 해주며, markup language는 필요치 않다.
  • 다트는 생산적이고 예측 가능한 언어이다. 배우기 쉽고 친숙하다. 여러분이 동적언어(dynamic language)를 사용해 왔든 정적언어(static language)를 사용해 왔든 쉽게 시작 할 수 있다.
  • 그리고 나는 같은 회사에서 만든 언어를 사용하는 것이 매우 매력적이라는 생각이 들기도 한다. 왜냐면 플러터 팀은 다트 팀과 긴밀히 협력하여 필요로 하는 새로운 기능을 구현할 수 있었기 때문이다.

Flutter vs. React Native ( 및 기타 선택 )

여러분의 다른 선택에 대한 나의 의견을 제시하기 전에 이것을 분명히 말하고 싶다. 플러터는 100% 정답이 아니다. 그것은 도구이고 우리는 당면한 일에 적합한 도구를 선택해야 한다는것이다. 즉 나는 이것이 미래에 여러분이 강력하게 고려해야 할 것이라고 주장 할뿐이다.

Native develoment(iOS and Android)

여러분의 첫번째 선택은 iOSAndroid native앱을 쓰는 것이다. 이것은 최대한의 제어와 디버깅 도구, 그리고 (잠재적으로) 성능 좋은 앱을 제공한다. 이말은 회사에서 모든것(개발대상)을 각 플랫폼마다 한번씩, 두번 작성(개발)해야 한다는 것을 의미한다. 여러분이 서로 쉽게 도울 수 없는 다른기술을 가진 다른팀의 다른 개발자가 필요할 것이다.

React Native, WebViews, and other cross-platform JavaScript options

여러분의 두번째 선택은 WebViewsReact Native와 같은 자바스크립트 기반의 cross-platform 이다. 이건 나쁜 선택이 아니다. 네이티브 개발로 겪는 문제가 사라진다. 팀의 모든 프론트엔드 웹 개발자는 최신 자바스크립트 기술만 알고 있으면 이를 지원(사용)할 수 있다.
AirBnb, Facebook, Twitter와 같은 대기업들이 React Native를 핵심 제품(서비스)에 사용한 것도 이런 이유에서이다. (AirBnb는 최근 아래 설명할 몇가지 이유로 인해 React Native 사용을 중지 한다고 발표했다.

첫번째 모바일 앱은(Airbnb의) WebKit(브라우저 렌더링 엔진)에서 실행되는 간단한 WebViews 였다. 문자 그대로 내장된 웹페이지다. 이것의 문제는 기본적으로 DOM조작이 매우 비싸고 훌륭한 모바일 경험(UX)을 만들 만큼 성능이 좋지 않다는 것이다.

일부 플래폼에선 Javascript Bridge를 구축하여 이런 문제를 해결 했다. 이 브릿지는 자바스크립트가 네이티브 위젯과 직접 대화(통신) 할 수 있게 한다.

이것은 WebViews보다 훨씬 더 뛰어난 성능을 발휘 하지만 여전히 이상적이진 않다.
앱이 렌더링 엔진과 직접 대화(통신)할때 마다 브릿지를 위해 네이티브 코드로 컴파일 되어야 한다.
단일 상호 작용에서 브릿지는 두 번 교차해야 한다. 한번은 플랫폼에서 앱으로 그리고 다시 앱에서 플랫폼으로.


Single interaction

플러터는 Chrome에서 사용하는것과 동일한 렌더링 엔진인 Skia를 자체 렌더링 엔진으로 사용하기 때문에 다르다. Skia는 플러터 앱과 통신 할 수 있다. 그 결과 로컬 이벤트를 자바스크립트로 먼저 컴파일 할 필요 없이 직접 받아 들인다.
플러터가 native ARM코드로 컴파일 되기 때문에 가능하고 이것이 성공의 비결이다. 여러분의 앱이 사용자의 장치에서 작동되면 이 앱은 전적으로 장치의 운영체제가 기대하는 언어로 실행된다.


Javascript bridge는 확실히 현대적 프로그래밍의 경이로운 부분이지만, 세 가지 큰 문제가 존재한다.

첫번째 문제는 디버깅이 어렵다는 것이다. 런타임 컴파일러에 오류가 있을 경우 해당 오류를 자바스크립트 브릿지를 통해 추적하여 자바스크립트 코드에서 찾아야 한다. 그것은 마크업 또는 CSS와 같은 구문 일 수도 있다. 디버거는 우리가 원하는 만큼 잘 작동하지 않을 수도 있다.

두번째로 큰 문제는 성능이다. 자바스크립트 브릿지는 매우 비싸다. 앱에서 무언가 탭(tapped)될 때마다 해당 이벤트가 브릿지를 통해 자바스크립트 앱으로 전송되어야 한다. “적절한 용어를 찾지 못하겄다! 걍 jank다.” (jank는 품질에 문제가 있는것들을 의미함. )

세번째로 큰 문제는 AirBnb에 따르면 그들은 자신들이 원하던 것보다 더 자주 native 코드를 까봐야 한다는 것을 발견했다고 한다. 그것은 대부분 자바스크립트 개발자로 구성된 팀들의 문제였다.

플러터의 즉각적인 이점

이 글을 읽고 있으니 플러터에 관심이 있을 수도 있지만… 회의적일 수도 있다. 나는 여러분의 철저한 기술조사에 존경(감탄) 한다.
여러분의 회의적인 이유는 타당하다. 그것은 새로운 기술이다. 이는 API의 변경사항을 깨뜨리는 것을 의미 한다. 이는 중요한 기능 (예: 구글지도)에 대한 지원이 누락 되었음을 의미한다. 구글이 언젠가 그것을 포기 할 수도 있다.

그리고 여러분이 다트가 훌륭한 언어라고 믿는 사실에도 불구하고, 다트가 널리 사용되지 않고 여러분이 원하는 third-party 라이브가 존재하지 않을 수도 있다는 사실은 변하지 않는다.

하지만 나는 그 모든 점들에 대해 논쟁을 벌일 것이다. 구글은 Google AdWords를 포함한 주요 수익 창출 앱에서 내부적으로 플러터를 사용하기 때문에 API는 바뀔것 같지 않다.

다트는 최근 버전2로 변경됐고, 이는 대 규모 변경이 있기까진 시간이 걸릴 것이라는걸 의미한다.
컴퓨터 세계에서 사실상 영구적인 변경이 소개 되기까지는 수년이 걸리지 않는가…

맞습니다. 실제로 누락된 기능들도 있지만 플러터는 여러분에게 여러분 고유의 native 플러그인을 추가 할 수 있는 완전한 제어권을 제공한다.
사실 map, camera, location service, device storage와 같은 가장 중요한 operationg system플러그인은 이미 존재한고 다트와 플러터의 생태계 커뮤니티도 이미 존재한다. 물론 자바스크립트 커뮤니티보다 훨씬 작지만 간결하다고 주장 하고 싶다. 나는 매일 새로운 패키지를 만드는 대신 기존 패키지에 기여 하는 사람들을 봤다.

이제 플러터의 구체적인 이점에 대해 얘기해 보자.

No JavaScript bridge

이것은 개발 및 응용프로그램 성능의 주요 병목이다. 다시 말하지만 이것은 jank로 이어진다. (위에도 jank에 대해 언급 했지만 한마디로 x같다.임)
스크롤이 매끄럽지 않고 항상 성능이 좋은것도 아니고 디버깅 하기도 어렵다.

플러터는 실제 native코드로 컴파일 되고 Skia를 사용해서 렌더링 된다. 앱 자체도 native로 실행되므로 다트를 native로 변환할 이유가 없다.
이는 사용자의 기기에서 실행될 때 어떠한 성능이나 생산성을 잃지 않는다는것을 의미한다.

Compile time

여러분이 만약 native개발자 라면, 여러분의 큰 고통 중 하나는 개발주기 였을겁니다. iOS의 미친 컴파일 시간은 악명이 높다. 플러터에서 전체 컴파일은 일반적으로 30초 미민이며, 핫 리로드 덕택에 증분 컴파일은 초 단위 이다. 플러터의 이런 개발주기 덕분에 우리는 모바일 클라이언트를 위한 기능을 빠르게 개발 할 수 있게 되었다. 구현히 확실할때만 웹 클라이언트에 이러한 기능을 개발한다.

Write once, test once, deploy everywhere (한번의 개발, 한번의 테스트, 어디에나 배포)

앱을 한 번만 작성하고 iOSAndroid에 배포 할뿐만 아니라 테스트를 한번만 작성하면 된다. 다트 unit테스트는 아주 빠르고 플러터는 테스트용 Widget들을 포함하고 있다.

Code sharing (코드 공유)

나는 여기서 공평해질꺼다. 나는 이것이(코드공유) 자바스크립트에서도 기술적으로 가능하다고 생각한다. 하지만 확실히 native개발에선 불가능하다. 플러터와 다트를 사용하면 웹 및 모바일 앱이 각 클라이언트들의 뷰를 제외한 모든 코드를 공유 할 수 있다.(물론, 다트를 통해서 웹 앱을 만든 경우에만 해당). 의존성 삽입을 사용하여 동일한 modelcontrollerAngularDar앱과 플러터 앱을 쉽게 실행 할 수 있다.

물론 웹앱과 모바일 앱간에 코드 공유를 하고 싶지 않더라도 모든 코드를 iOSAndroid앱간에 공유 할 수 있다.

실용적인면에서 이것은 여러분이 매우 생산적이라는것을 의미 한다. 앞서 말했지만 우리 회사는 먼저 모바일 기능을 개발한다. 왜냐면 웹과 모바일간에 비지니스 로직을 공유하기 때문에 일단 모바일 기능이 구현되면 동일한 컨트롤러 데이터를 필요로 하는 view만 작성하면 되기 때문이다.

Productivity and collaboration (생산성과 공동작업)

iOSAndroid용 팀이 분리 되는 시대는 끝났다. 사실 여러분이 여러분의 웹 앱에서 다트를 사용하든, 자바스크립트를 사용하든 간에, 플러터 개발은 여러분의 모든 팀이 통합될 정도로 충분히 친숙하다. 자바스크립트 웹 개발자가 플러터와 다트에서도 효과적으로 개발할 것으로 기대하는건 결코 쉬운 일이 아니다. 여러분이 나를 믿는다면, 여러분의 새로운 통합팀은 3배 더 생산적인 팀이 될 것 이다.

Code maintenance (코드 유지보수)

버그를 한번 고치는게 모든 client를 고친는것 보다 났다는것은 두말 하면 잔소리지만 매우 특정한 경우에 한해선 플러터로 제작된 iOS앱에 버그가 있다면 Android 버전에도 존재한다. (반대의 경우도 마찬가지) 이런한 경우 100% 이러한 버그는 버그가 아니라 내장된 위젲의 기기 OS설계 시스템을 따르기 때문에 외관상의 문제가 된다. 이러한 문제는 텍스트 크기 조정 또는 정렬과 같은 문제이기 때문에 엔지니어링 시간을 사용하여 수정하는 맥락에서 보면 사소한 것이다.

Flutter for JavaScript developers (자바스크립트 개발자들을 위한 플러터)

CSS-Tricks를 읽어 있으니 나는 여러분이 웹 개발자라 확신한다.(역자주: CSS-Tricks가 뭔지를 모르겠음) 만약 여러분이 오늘날 가장 인기 있는 framework을 사용한다면, 여러분이 플러터를 줍는게(공부하는게) 쉽다는 것을 알게 되어 기뻐할 것이다.

플러터는 완전히 반응형(reative)이기 때문에 React에서 익숙해진 동일한 사고방식과 패러다임이 플러터로 이어진다.
여러분은 기본적으로 React처럼 재사용할 수 있는 수 많은 컴포넌트(풀루터에선 Widget이라고 부름)를 만들고 있을 것이다. 이 위젯들은 라이프 싸이클(life cycle)메소드로 완성되며, 클래스(class)로 작성된다.

React에서 이 구문을 사용한 경우:

1
2
3
4
const MyComponent extends React.Component {
//...
render(){}
}

…그리고 아무 문제 없이 플러터를 잡을 것이다. 플러터에서 동일한 작업을 수행하는 방법은~

1
2
3
4
class MyWidget extends StatelessWidget {
//...
build(){}
}

그리고 React와 마찬가지로 플러터에서도 상속(inheritance)보다는 구성(composition)을 선호한다.
예를 들어 여러분이 React에서 특별한 AddToCartButton을 만들기 원한다면, JSX의 특별한 함수와 스타일을 사용하여 버튼을 만들 수 있다. 플러터에서도 정확히 그렇게 하는 거다. (JSX는 제외하고~)

마지막으로 플러터의 레이아웃(Layout) 시스템은 우리에게 익숙한 CSS규칙, 즉 flexbox와 절대위치 지정(absolute positioning)과 비슷하다.
이것은 또한 플러터의 view를 만드는데 있어 큰 차이점이 있다. 플러터에선 문자 그대로 모든것이 위젯(Widget)이다. Text, ButtonAppBar와 같은 명확하고 구체적인 위젯이 있고 Animations, Layout 또한 위젯이다. Text를 가운데로 정렬하기 위해 Center위젯으로 Text 위젯을 감싼다. 패딩(padding)을 추가하려면 Padding이 있다.

React 앱을 가능한 가장 작은 재사용 가능한 구성 요소로 분해 한다고 상상해 보자. 예를 들어 여러분이 단순히 Padding 속성을 다루는 고차원의 React 컴포넌트를 만든 경우 그 중첩된 패딩을 해당 패딩 양만큼 추가하면 된다. 이것이 CSS나 마크업 없이 플러터가 작동하는 방식이다.

이 샘플 그림에서는 사용할 수 있는 몇 가지 레이아웃 위젯을 설명하지만 사용자로서 '참조’할 수는 없다:

Examplelayout
엄청나게 단조로운 작업처럼 보일 수 도 있지만, 플러터에는 (PaddingCenter와 같은) 내장된 아주 많은 위젯들이 있기 때문에 여러분은 쓸때 없이 시간을 낭비할 필요가 없다.

다음은 가장 일반적인 위젯 중 하나이다.

Final note

플러터를 사용해 보겠는가?
만약 여러분이 버터같은 부드러운 모바일 앱을 익숙한 스타일로 만들고 싶다면, Yes! 성능과 개발자 경험 모두 플러터에서 완전하게 유지된다.
애니메이션은 60fps에 달하며 내장된 Cupertino-styleMaterial Design-style의 위젯이 번들로 제공되며 간단히 말해, native 성능을 희생하지 않고 플러터에서 얼마나 빨리 생산적으로 작업 할 수 있는지는 믿기 힘들정도 이다.