iBetter Books
수정

WASM으로 내보내기 (브라우저 단독 실행)

서버를 운영하지 않고도 노트북을 공유하는 방법이 있습니다. WASM(WebAssembly) 내보내기가 그것입니다. 내보낸 결과물은 진입점 index.html과 런타임·자원이 담긴 하나의 디렉토리입니다. 이 페이지를 브라우저에서 열면 서버 없이도 Python 코드가 실행됩니다.

어떻게 가능한 걸까요?

Pyodide — 브라우저에서 실행되는 Python

WASM 내보내기의 핵심은 Pyodide입니다. Pyodide는 CPython을 WebAssembly로 포팅한 프로젝트입니다. 브라우저의 WebAssembly 런타임에서 Python 인터프리터 자체가 동작합니다.

marimo가 WASM으로 내보낸 디렉토리의 index.html에는 이 Pyodide가 포함됩니다. 사용자가 브라우저에서 페이지를 열면 Pyodide가 초기화되고, 함께 담긴 노트북 코드를 실행합니다. Python 서버도, 인터넷 연결도 필요 없습니다. 모든 것이 브라우저 안에서 완결됩니다.

단, 이 방식에는 중요한 제약이 있습니다. 다음 챕터에서 자세히 다루지만, 모든 Python 패키지가 WASM 환경에서 동작하는 것은 아닙니다. 이 챕터에서는 먼저 내보내는 방법을 익히고, 제약은 Ch 03에서 살펴보겠습니다.

내보내기 명령

디렉토리로 내보내기

html-wasm 내보내기의 결과물은 항상 디렉토리입니다. -o에 지정한 경로가 출력 디렉토리 이름이 됩니다.

marimo export html-wasm notebook.py -o output_dir

output_dir 디렉토리 안에 진입점인 index.html과 Pyodide 런타임, 노트북 코드, 정적 자원(assets 등)이 함께 생성됩니다. 단일 HTML 파일 하나로 떨어지는 것이 아니라, 이 디렉토리 전체를 묶어 배포해야 합니다. 그래서 GitHub Pages나 Cloudflare Pages처럼 디렉토리 단위로 올리는 정적 호스팅에 잘 맞습니다.

편집 가능 모드로 내보내기

marimo export html-wasm notebook.py -o output_dir --mode edit

--mode edit를 추가하면 브라우저에서 코드를 직접 수정할 수 있는 편집 모드로 내보냅니다. 기본값은 read-only 실행 모드입니다.

편집 모드는 교재 실습 파일을 배포할 때 유용합니다. 독자가 브라우저에서 직접 코드를 수정하고 실행 결과를 확인할 수 있습니다. 협업 편집이 아니라 개인 브라우저 내부에서의 수정이므로, 다른 사람의 화면에는 영향을 주지 않습니다.

Cloudflare Pages 배포용

marimo export html-wasm notebook.py -o output_dir --mode edit --include-cloudflare

--include-cloudflare 플래그는 Cloudflare Pages 배포에 필요한 설정 파일을 함께 생성합니다. Ch 05에서 배포 절차를 다룹니다.

반드시 HTTP로 서빙해야 합니다

WASM 내보내기의 중요한 제약 하나를 짚어야 합니다. 내보낸 HTML 파일을 파일 탐색기에서 더블클릭해 브라우저로 열면 작동하지 않습니다.

이유는 브라우저의 보안 정책 때문입니다. file:// 프로토콜로 열린 페이지는 교차 출처 자원 접근이 차단됩니다. Pyodide가 필요한 파일들을 로드할 수 없어 Python 실행이 시작되지 않습니다.

로컬에서 결과를 확인하려면 반드시 HTTP 서버를 통해 서빙해야 합니다.

cd output_dirpython -m http.server 8000
Serving HTTP on :: port 8000 (http://[::]:8000/) ...

브라우저에서 http://localhost:8000/을 열면 디렉토리의 index.html이 로드되고 WASM이 정상적으로 실행됩니다.

GitHub Pages나 Cloudflare Pages 같은 정적 호스팅 서비스는 자체적으로 HTTP 서빙을 제공하므로, 실제 배포 시에는 이 문제가 없습니다. 로컬 확인 단계에서만 주의하면 됩니다.

내보내기 시 Pyodide가 초기화되는 데 시간이 걸립니다

WASM 파일을 처음 브라우저에서 열면 로딩 화면이 나타납니다. Pyodide 런타임을 초기화하고 필요한 패키지를 설치하는 과정입니다. 수 초에서 십수 초가 걸릴 수 있습니다. 이후 위젯 조작은 일반적인 반응 속도로 작동합니다.

내보내기 형식 5가지 중 WASM의 위치

marimo가 지원하는 내보내기 형식은 다섯 가지입니다.

형식 명령 특징
html marimo export html 정적 HTML, 실행 결과를 스냅샷으로 포함. 상호작용 없음
html-wasm marimo export html-wasm 브라우저에서 Python 실행. 상호작용 유지
ipynb marimo export ipynb Jupyter 형식으로 변환
md marimo export md 마크다운으로 변환 (Quarto/MyST 연동)
script marimo export script 위상정렬된 순수 Python 스크립트

이 중 html-wasm만이 서버 없이 위젯이 동작하는 인터랙티브 결과물을 만듭니다. html은 정적 스냅샷이므로 위젯을 조작해도 Python이 실행되지 않습니다.

다음 단계

WASM이 강력한 배포 수단이라는 것은 분명합니다. 서버 없이 Python이 동작하는 페이지를 배포할 수 있다는 것은 큰 장점입니다. 그런데 여기에 중요한 전제가 있습니다. 앱에서 사용하는 패키지가 WASM 환경에서 동작해야 합니다. 다음 챕터에서 그 제약을 살펴보겠습니다.

정리

  • marimo export html-wasm notebook.py -o 출력경로로 노트북을 브라우저 단독 실행 형식으로 내보냅니다.
  • 내보낸 결과물은 Pyodide(CPython WebAssembly 포트)를 포함하며, 브라우저 안에서 Python 코드를 실행합니다.
  • 로컬 확인 시 python -m http.server로 HTTP 서버를 실행해야 합니다. 파일을 직접 브라우저로 열면 동작하지 않습니다.
  • --mode edit를 추가하면 브라우저에서 코드를 직접 수정할 수 있는 편집 모드로 내보냅니다.
  • 디렉토리로 내보낸 결과물은 GitHub Pages나 Cloudflare Pages 같은 정적 호스팅에 바로 배포할 수 있습니다.