빌드

화면이 서버에서 온다 — 클라이언트가 화면을 하나도 안 갖고 있으면

작성: makemind · 2026년 7월 6일

지금까지 이 시리즈의 샘플은 전부 화면 파일을 앱 옆에 뒀다. .mbd 폴더가 클라이언트와 같이 배포된다.

둘의 주인이 같으면 그게 맞다. 화면을 바꿀 사람과 앱을 배포할 사람이 같은 사람이니까.

문제는 화면의 주인이 앱의 주인이 아닐 때다.

  • 로비에 걸린 디스플레이 — 건물 관리자가 화면을 바꾸고 싶다
  • 프랜차이즈 매장 보드 — 본사가 바꾸고 점주는 안 건드린다
  • 제조사가 출하하는 패널 — 화면은 제조사 것이고 앱은 통합업체 것이다

이런 경우에 화면을 앱에 넣어 두면 화면을 바꿀 때마다 앱을 다시 배포해야 한다. 그리고 그 배포는 화면을 바꾸고 싶은 사람이 못 한다.

클라이언트가 아무것도 안 갖는다

client ships: no library files at all, and no lib/ directory
server offers: ui://board, data://board

이 샘플의 클라이언트에는 lib/ 디렉터리 자체가 없다. .mbd 번들도 없다. 화면을 설명하는 파일이 클라이언트 쪽에 한 장도 없다.

검증이 그걸 지킨다.

STRAY=$(find bundle_host -name '*.json' -not -path '*/.dart_tool/*' -not -path '*/build/*' -not -name 'package_config.json' | wc -l | tr -d ' ')
[ "$STRAY" -eq 0 ] || { echo "   $STRAY json file(s) on the client — it is not screenless"; exit 1; }
[ ! -d bundle_host/lib ] || { echo "   the client has a lib/ — it should need none"; exit 1; }
MBD=$(find . -maxdepth 1 -name '*.mbd' | wc -l | tr -d ' ')
[ "$MBD" -eq 0 ] || { echo "   there is a bundle here — this sample serves the screen instead"; exit 1; }

이 검사가 이 편의 전부다. 나중에 누가 "편의상" 화면 하나를 클라이언트에 두는 순간 실패한다.

서버가 화면을 리소스로 내놓는다

// The screen itself, as a resource. A client that can read this needs to
// ship nothing.
server.addResource(
  uri: _screenUri,
  name: 'Board screen',
  description: 'The screen definition this board should draw',
  mimeType: 'application/json',
  handler: (uri, params) async => ReadResourceResult(
    contents: [
      ResourceContentInfo(
        uri: _screenUri,
        mimeType: 'application/json',
        text: File(_live).readAsStringSync(),
      ),
    ],
  ),
);

화면과 데이터가 다른 리소스다. ui://boarddata://board.

나눈 이유는 갱신 빈도가 다르기 때문이다. 가격은 하루에도 몇 번 바뀌고 레이아웃은 계절에 한 번 바뀐다. 같이 묶어 두면 가격 하나 바꿀 때마다 레이아웃 전체가 다시 온다.

첫 화면

CORNER COFFEE — Americano 3,800 / Latte 4,300 / Cold brew 4,800 / Scone 3,200. served from screens/v1_list.json
CORNER COFFEE — Americano 3,800 / Latte 4,300 / Cold brew 4,800 / Scone 3,200. served from screens/v1_list.json
drew "Board v1" (sha256:592cd36cd4d0, 59 lines) — generation 1

클라이언트는 이 화면을 처음 본다. 코드 어디에도 "Americano" 도 "가격은 오른쪽 정렬" 도 없다.

이 콘텐츠는 개발자 이상이 필요합니다

로그인 후 플랜을 업그레이드하면 계속 읽을 수 있습니다.

플랜 보기
Twitter