본문 바로가기
C.W.K.
Stream
Lesson 03 of 07 · published

plugin-store로 영속화 (와 localStorage가 거짓말하는 이유)

~14 min · tauri, store, persistence, macos

Level 0웹 관광객
0 XP0/56 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"개발 내내 멀쩡했는데, 진짜 사용자가 빌드된 앱을 열었더니 설정이 죄다 사라져 있었어. 웹뷰 저장소의 세계에 온 걸 환영해."

내보낸 뒤에야 얼굴을 내미는 함정

익숙한 웹 도구를 꺼내지. localStorage, 어쩌면 Zustand persist 미들웨어 뒤에 두고. tauri dev에선 완벽하게 왕복해. 설정이 저장되고 다시 불러와지고, 아무 문제 없어. 그러고 나서 진짜 .app을 빌드하고 서명해서 누군가한테 건네면, 두 번째로 켤 때 값이 전부 없어져 있어. 네 코드는 한 줄도 안 바뀌었는데. 밑에 깔린 저장소 층이 바뀐 거야.

macOS WKWebView localStorage가 왜 안 버티나

진짜 이유는 이래, Cinder가 호되게 배운 거고. 개발할 땐 프론트엔드가 Vite origin(http://localhost:1420)에서 서빙되는데, 그게 WebKit 데이터 디렉터리를 계속 살려두니까 localStorage가 남아. 근데 번들되고 서명된 macOS .app 안에서는, 앱 샌드박스랑 서명이 걸린 상태에선 WKWebView 데이터 디렉터리가 실행과 실행 사이에 초기화될 수 있어 — 그래서 거기선 localStorage가 사실상 일회용이야. JS로 고칠 수 있는 버그가 아니야. macOS에서 웹뷰 저장소가 놓인 자리의 성질이야.

해결책: Rust 쪽에 저장해

store 플러그인이 이 질문 자체를 비껴가. 웹뷰 저장소를 믿는 대신 Rust에서 앱 config 디렉터리에 JSON을 써 — macOS라면 ~/Library/Application Support/<네.identifier>/ 아래에. 그건 OS가 지우지 않는 진짜 파일이라 앱을 다시 켜도, 샌드박스가 초기화돼도 버텨. 여기서 나오는 규칙은 이거야. Tauri 앱에서 오래 남아야 하는 설정은 store 플러그인(이나 다른 Rust 쪽 저장 경로)에 속하지, 웹뷰 localStorage엔 절대 아냐.

Code

store 플러그인: 진짜로 남는 저장·ts
import { LazyStore } from "@tauri-apps/plugin-store";

// JSON을 Rust로 앱 config 디렉터리에 써 — 재시작을 견뎌.
// macOS: ~/Library/Application Support/<네.identifier>/settings.json
const store = new LazyStore("settings.json");

await store.set("theme", "dark");
await store.save();              // 디스크로 flush

const theme = await store.get<string>("theme"); // 재실행 후에도 "dark"
개발 중엔 거짓말하고, 빌드된 앱이 진실을 말해·text
왜 중요한가 (Cinder의 추론, 농축):

  dev (npm run tauri dev)        빌드+서명된 .app
  ─────────────────────────      ─────────────────────────
  localhost:1420에서 서빙         Vite origin 없음
  WebKit 데이터 디렉터리 따뜻      WKWebView 디렉터리 재실행시 리셋 가능
  localStorage 왕복 ✓            localStorage 조용히 비워짐 ✗

  → store 플러그인(Rust → config 디렉터리) 설정은 둘 다 견뎌.

External links

Exercise

store 플러그인을 넣고 설정 하나(테마 토글 같은 거)를 그걸로 저장해봐. 앱을 껐다 다시 켜서(먼저 개발 모드에서) 되돌아오는지 확인해. 그다음 만약 빌드한 macOS .app에서 localStorage를 썼다면 무슨 일이 났을지, store 플러그인은 왜 그 운명을 피하는지 한 문장으로 예측해서 적어.
Hint
LazyStore('settings.json')에 store.set/get/save. 예측은 이래. localStorage는 개발 중엔 버텨도 번들된 .app에선 WKWebView 데이터 디렉터리가 초기화될 수 있어서 날아가고, store 플러그인은 OS가 지키는 config 디렉터리에 진짜 파일을 써.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.