Compose Multiplatform (wasm, js)으로 웹 개발 도전기

covy·2024년 9월 8일

먼저 완성품을 공개합니다.

랜딩페이지 링크 바로가기

서론

현재 우리 서비스에서 랜딩 페이지 디자인은 되어 있지만, 개발은 되어있지 않다.

이를 현재 주목받고 있는 compose multiplatform으로 개발을 도전하려고 한다.

왜 compose냐..
1. web 개발자가 없는 상태에서 안드로이드 개발스택으로 UI 개발 가능함
2. 하는 사람이 많이 없어서 개척한다는 기대감
3. 기술 바이럴 -> 서비스 바이럴 마케팅? (희망사항)

조사결과 그러기엔 많은 부담이 있었다.
compose web은 wasm로 개발이 가능한데, wasm이 safari등 GC 기능이 지원되지 않는 브라우저는 호환이 안되는 문제가 있다. (이는 safari뿐만 아닌 모바일 chrome 브라우저도 포함된다.)

다행히도 코틀린 슬랙채널 에서 JS에 wasm을 올리는 방법으로 해결한다는 대화를 확인하고, 바로 프로젝트 오픈을 눌렸다.

프로젝트는 kmp 위자드에서 생성하면 편하다.

삽질기

여러가지 문제들 중 막혔던 과정이 3가지가 있었다. 이 삽질 이야기를 이번 블로그에 풀어보고자한다.
1. kotlin에서 kotlinx.browser을 사용하려면 js 또는 wasm 모듈에서만 사용 가능하다.
2. 모듈 설정 wasm에서 js 빌드 이전
3. github pages로 배포

1. kotlin에서 kotlinx.browser을 사용하려면 js 또는 wasm 모듈에서만 사용 가능하다.

다른 화면으로 이동하기 위해서 어떻게 할 수 있을까? 라는 서칭 끝에 kotlinx.browser 라는 라이브러리가 필요한데, 이는 wasm/js 모듈에만 내장되어 있다.

현재 commonMain 모듈에서 화면을 구현하고 있는데, 화면 이동은 어떻게 할 수 있을지 고민이 되었다.

해답은 어렵지 않다. 상태 호이스팅을 하자 아래와 같이 이벤트를 끌어올려서 사용하고 있는 모듈에서 browser 메소드를 호출하면 된다.
나는 window.open을 사용했다.

@OptIn(ExperimentalComposeUiApi::class)
fun main() {
    onWasmReady {
        ComposeViewport(document.body!!) {
            App(
                onPlayStoreClick = {
                    window.open("https://play.google.com/store/apps/details?id=com.withpeace.withpeace")
                },
                onAppStoreClick = {
                    window.open("https://apps.apple.com/kr/app/%EC%B2%AD%ED%95%98/id6504498223")
                }
            )
        }
    }
}

2. 모듈 설정 wasm에서 js 빌드 이전

서론에서도 언급했듯이, 현재 wasm 모듈로 배포시 사파리나, 모바일에서 작동이 안된다.(GC 미지원으로 인함)
해결방안으로 js 모듈에 -> wasm 을 사용해서 그 위에 compose를 돌리는 방식으로 가능하다.

결론은 js 모듈을 빌드한다고 생각하면된다.
js 모듈의 코드는 다음과 같이 구성된다.

/jsMain/mainJs.kt

@OptIn(ExperimentalComposeUiApi::class)
fun main() {
    onWasmReady {
        ComposeViewport(document.body!!) {
            App(
                onPlayStoreClick = {
                    window.open("https://play.google.com/store/apps/details?id=com.withpeace.withpeace")
                },
                onAppStoreClick = {
                    window.open("https://apps.apple.com/kr/app/%EC%B2%AD%ED%95%98/id6504498223")
                }
            )
        }
    }
}

주의) wasm을 쓰는 것이지 wasm 모듈을 쓰는 것이 아니다. 모든 웹 브라우저에서 실행시키려면, js 모듈만 필요하다.

3. github pages로 배포

공식문서 에서 배포방법을 공유하고 있지만, 정상적으로 배포되지 않았다.

따로 workflow를 작성해서 빌드 및 배포로직을 작성했다.

https://github.com/WithPeace/cheongha.github.io/blob/main/.github/workflows/ci.yml

코드 링크

Github 링크도 함께 공유합니다.

링크: https://github.com/WithPeace/cheongha.github.io

결론

alpha 단계 기술로 프로덕션 수준을 만들기는 어렵다고 몸소 느꼈다.
트러블 슈팅을 위해 kotlin slack 채널에 웹 관련 모든 코멘트를 찾아봤다.
그럼에서 초기 폰트, 이미지 렌더링 문제 등 아직 풀어야 할 문제가 많다.

하지만 장점으로 본다면, wasm으로 빌드했을 때 만족스러운 실행속도와 compose로 공통 코드를 쓸 수 있다는 것은 정말 멋진 매력이 있다.
적어도 모바일 웹 UI를 구성할 때 효율적일 것 같다.

앞으로 기술 소식을 기다리면서 개선해볼 생각이다.

0개의 댓글