[dioxus] 소개 및 시작

dioxus는 Rust 언어 기반의 클라이언트 개발 프레임워크다.
다양한 타겟을 지원하며, SSR/CSR도 있고 프론트엔드 프레임워크로서 있을만한건 얼추 다 있다.




지원 플랫폼

이건 웹-프론트엔드만 지원하는 것이 아니라, 일반 gui, ios, android 또한 지원하는 멀티플랫폼 프레임워크다. 이런 면에서는 flutter와 비슷하다.

https://dioxuslabs.com/learn/0.7/
단일 소스로 여러개의 플랫폼에서 동작하는 앱을 만들 수 있다.




설치

사전에 필요한 세팅이 몇가지 있다.
먼저 wasm 타겟을 추가해줘야 한다. wasm을 여러 부분에 활용하기 때문이다.

rustup toolchain install stable
rustup target add wasm32-unknown-unknown

그리고 전용 CLI 도구도 필요하다. 이걸 통해서 프로젝트 구성, 빌드, 배포에 이르는 전반적인 라이프타임 관리를 숏컷으로 처리할 수 있다.

curl -sSL https://dioxus.dev/install.sh | bash




프로젝트 생성과 기본구조

그럼 이제 dx CLI을 통해서 프로젝트를 간편하게 구성할 수 있다.
dx new 명령을 사용하면 대화형 터미널을 통해 프로젝트 생성 컨텍스트가 시작된다.

적당히 필요한대로 고르면 된다. 나는 기본적인 것들만 넣었다.

그리고 생성하면, 이런 식으로 프로젝트가 구성될 것이다.

assets 경로에 static assets들이 추가된 것이 꽤 특이한 부분이다.

그리고 소스코드는 이런 식으로 만들어져있을 것이다.

그렇게 복잡하진 않다.


애셋은 매크로를 통해서 소스코드 내에 통합되는 형태를 가진다.
그렇다고 완전한 컴파일타임 로드는 아니다. 경로 정보가 컴파일타임에 들어갈뿐, 실제 데이터 로드는 런타임에 이뤄진다.


소스코드는 이런 식이다. Root 컴포넌트를 launch로 시작해서 앱이 시작되는 구조이고, 전용 매크로 컨텍스트를 통해서 DOM Tree 구조를 정의한다.
yew 등의 다른 프레임워크들과 비슷한 방향성이다.


그리고 컴포넌트 안에는 또 다른 컴포넌트가 들어갈 수 있다.




프로그램 실행 (웹)

dx serve 명령을 사용하면 웹 버전으로 앱을 실행해볼 수 있다.

dx serve

부팅은 꽤 빠르다.
webpack처럼 개발서버를 띄우고 개발서버를 통해서 실제 HTML 등이 서빙되는 구조다.

그럼 이런 식으로 접근이 될 것이다.




배포: web

dx serve는 개발서버를 띄우는 명령이기 때문에 그 자체로는 정적 페이지를 배포할 수는 없다.
만약 html으로 구성된 정적 페이지의 배포가 필요하다면, bundle 명령을 사용해서 말아버릴 수 있다.

dx bundle --web

빌드타임은 그렇게 느리지 않다.


빌드가 성공하면, target의 dx 경로 아래에 최종 번들이 생성된다.
저 안의 public을 통째로 가져다가 배포하면 되는 것이다.

wasm, js, css, 이미지 등이 포함되고, index.html을 가져다가 실행하면 개발한 그대로 실행이 될 것이다.




Hot Reload (Auto Reload)

dioxus는 개발 편의성이 꽤 뛰어난 편이다.
소스코드를 변경 후 저장하면, 자동으로 빠르게 재시작해서 반영해주는 auto reload를 지원한다.




VSCode 확장

dioxus는 IDE 환경에도 노력을 꽤 들인다.
VSCode에도 공식 확장이 존재한다.

이걸 사용하면 rsx 매크로 컨텍스트 내에서의 오토 포맷팅이 가능해지고, HTML -> dioxus 코드 변환도 가능해진다.

예를 들어 코드 내에 이런 식으로 html을 넣은 다음에

명령을 사용하면

적절히 변환되는 것이다.

rsx 코드로도 변환이 되고, component 단위로도 변환이 된다.




GUI 앱 빌드하고 배포하기

dioxus는 일반 데스크톱 환경에서의 gui 개발 또한 기반으로 제공한다. 웹뷰-tauri 기반이다.
macOS나 windows는 딱히 뭐가 더 필요하진 않는데, Linux의 경우에는 웹뷰 관련 추가 사전 종속성이 있다.

# 데비안 계열 
sudo apt update
sudo apt install libwebkit2gtk-4.1-dev \
  build-essential \
  curl \
  wget \
  file \
  libxdo-dev \
  libssl-dev \
  libayatana-appindicator3-dev \
  librsvg2-dev \
  lld

# Arch 계열
sudo pacman -Syu
sudo pacman -S --needed \
  webkit2gtk-4.1 \
  base-devel \
  curl \
  wget \
  file \
  openssl \
  appmenu-gtk-module \
  libappindicator-gtk3 \
  librsvg \
  xdotool

dx serve에 desktop 플래그만 넣으면, 그 즉시 데스크탑 gui 버전으로 빌드해서 실행한다.

dx serve --desktop # 현재 플랫폼으로 빌드

그리고 빌드한 결과물은 target의 dx 경로에 저장된다.

만약 특정 OS의 데스크톱을 명시적으로 빌드하고 싶다면, 현재 OS와 다르더라도 전용 플래그를 줘서 빌드할 수 있다. 다음 명령은 macos에서 동작하는 바이너리를 생성한다.




모바일 앱 빌드 (Android)

모바일앱은 사전 구성이 이것저것 필요하고, iOS의 경우에는 MacOS만 개발가능하다.
XCode가 필요하기 때문이다.

안드로이드는 안드로이드 SDK과 NDK 정도만 깔려있으면 어디서든 사용할 수 있으니 안드로이드로 예시를 들어보이겠다.

안드로이드 스튜디오에서 NDK와 SDK CLI, CMAKE를 설치한다.

그리고 환경변수들을 설정해줘야 하는데, 내 Linux 환경에서는 이렇게 하면 됐다.

set -Ux JAVA_HOME "/opt/android-studio/jbr"
set -Ux ANDROID_HOME "$HOME/Android/Sdk"
set -Ux NDK_HOME "$HOME/Android/Sdk/ndk/29.0.14206865" # 맞춰서 변경
fish_add_path "$ANDROID_HOME/emulator" "$ANDROID_HOME/platform-tools"

MacOS에서는 다음 경로 추가가 필요하고

export JAVA_HOME="/Applications/Android Studio.app/Contents/jbr/Contents/Home"
export ANDROID_HOME="$HOME/Library/Android/sdk"
export NDK_HOME="$ANDROID_HOME/ndk/25.2.9519653" # 맞춰서 변경
export PATH="$PATH:$ANDROID_HOME/emulator:$ANDROID_HOME/platform-tools"

Windows는 이렇게 추가하면 된다.

[System.Environment]::SetEnvironmentVariable("JAVA_HOME", "C:\Program Files\Android\Android Studio\jbr", "User")
[System.Environment]::SetEnvironmentVariable("ANDROID_HOME", "$env:LocalAppData\Android\Sdk", "User")
[System.Environment]::SetEnvironmentVariable("NDK_HOME", "$env:LocalAppData\Android\Sdk\ndk\25.2.9519653", "User") # 맞춰서 변경

그리고 Rust에서도 타겟 추가가 필요하다.

rustup target add aarch64-linux-android armv7-linux-androideabi i686-linux-android x86_64-linux-android

준비가 다 됐다면, --android 플래그로 앱 빌드를 시작할 수 있다.

이 최초 빌드는 상당히 오래 걸린다.


빌드가 완료되면, 에뮬레이터가 켜지고 앱이 시작된다.


그리고 이것도 다른 플랫폼과 마찬가지로 hot reload가 가능하다.
최초 빌드 이후의 재빌드는 매우 빠르게 처리된다.


모바일 빌드의 결과물 또한 target dx 폴더에 생성된다.
이걸 그대로 말아서 스토어에 올리거나 번들링하면 된다.



참조
https://dioxuslabs.com/learn/0.7/getting_started/