

해당 레포: https://github.com/gronxb/hot-updater
hot-updater library의 console부분 UX를 고치고 난 후의 이야기이다.
링크
다 하고 나서 해당 라이브러리의 issue를 봤다.

firebase도 지원해주세요..!
https://github.com/gronxb/hot-updater/issues/110

우리는 firebase로 사용하고 있었어요 도입 가능 할까요?
답변은 아래와 같다.

진짜 좋은데, 절차상 후순위긴 하다. 누군가 만들어주면 좋을 것 같다
아래는 plugin 스펙이니 이거 따라 만들어주면 된다.

나: 내가 할게~~
해보자
내가 개발해야할 hot-updater에서 사용하는 서버 관련(?)은 아래와 같다.
기존 supabase 플러그인으로 예시를 들어놨길래 한번 들여다 봤다.

일단 모노 레포다.. 모노 레포를 다뤄본적이 없어서 이에 대해 알아봤다.
해보니 중요한건 아래와 같았다.
모노 레포가 처음엔 정말 정말 어지러웠는데, 하다보니 금방 적응이 되더라(맨날 이 말 하는 것 같다..)
supabase
|-scripts: init시 DB를 생성하는 script
|-src: 핵심 코드들
||-utils: 특정 함수 구현체
|||-index.ts: module로 불러올때 어떤 것을 import 할 수 있게 할지 정함
|||-supabaseApi.ts: API 불러오는거 몇 개 정리
|||-templates.ts: 데이터베이스 시딩이 비활성화된 Supabase 프로젝트 설정 TOML 파일 템플릿 정의
||-index.ts: module로 불러올때 어떤 것을 import 할 수 있게 할지 정함
||-supabaseDatabase.ts: Database CRUD 구현체
||-supabaseStorage.ts: Storage에 upload, delete하는 구현체
||-supabase: 클라이언트의 정보를 기반으로 DB의 정보 호출
첫 번째 단계인 Storage를 개발하려면 나는 supabaseStorage.ts 부분만 개발하면 된다.
그럼 얘가 어디서 호출되어서 어떻게 굴러가는지 나는 알아야 했다.
친절하게 example 프로젝트도 같이 공유가 되었는데, supabaseStorage의 호출부를 보자

이런 식으로 v0.77.0/hot-updater.config.ts에서 쓰이는 것을 볼 수 있다.
다른 plugin들은 어떻게 들어갈까?

결국 아래와 같은 답을 얻을 수 있었다.

이 형식에 맞는 값을 넣어주면 되겠구나.
그럼 얘네는 어디서 쓰이지?
이걸 찾는데 꽤나 오래 걸렸는데.. 테스트를 돌려보며 찾았었다.
Storage를 사용할 때가 새롭게 deploy를 할 때 였는데, 이에 대한 코드를 찾았었다.

결국 중요한 것은 모든 plugin은 서로 구현체는 다르지만, 결국 통일된 모습으로 하나의 로직으로 들어가 작동된다는 것이다.
정리는 했는데, 이해가 안가거나 모르는 부분들을 따로 공부하고 서치했다.

//root/package.json
"pnpm": {
"overrides": {
"@hot-updater/firebase": "workspace:*"
}
//plugins/firebase/src/index.ts
export * from "./firebaseStorage";
//shell
cd .../v0.77.0
pnpm add -D @hot-updater/firebase
cloudflare나 간혹 다른 곳에서 DB의 연결 종료를 해줘야 하는 경우에 사용하는 것이더라.
path는 node에서 제공하는 경로를 다루기 쉽게 해주는 것, fs는 파일을 읽고 쓰는데 도움을 주는 자체 라이브러리들이다.
//plugin/firebase
pnpm add -D @types/node
를 해주어야만 사용할 수 있다.
위와 같은 구조가 무엇인지 찾아보니 Adapter 패턴이었다.

이렇게 서로 다른 plugin들을 하나의 기능으로 통합시키는, 추상화 하는 녀석이 Adapter인데 이게 hot-updater.config.ts에서 하는 역할이더라.
추상화의 중요성을 깨달았다. 이 추상화 덕분에 supabase의 DB와 firebase의 storage를 넣어도 실행이 가능했다.
구현은 최대한 간단히..
프로젝트를 생성하고 코드를 구현했다. supabase storage를 많이 참고했다. 사실 비슷한 구석들이 많기에 같은 기능을 하는 메소드들로 넣었다.

hooks는 넣지는 않겠지만, 추후 사용자들이 slack에 알림을 보낸다거나 하는 메소드가 들어갈 수도 있기 때문에 남겨두었다.
중요하게 생각한 점은 2가지이다.
자세한건 PR 링크:https://github.com/gronxb/hot-updater/pull/149
/*
전
storage: supabase
DB: supabase
*/
import {stupabaseStorage, supabaseDatabase} from "@hot-updater/supabase";
export default defineConfig({
build: metro({
enableHermes: true,
}),
storage: supabaseStorage({
supabaseUrl: process.env.HOT_UPDATER_SUPABASE_URL!,
supabaseAnonKey: process.env.HOT_UPDATER_SUPABASE_ANON_KEY!,
bucketName: process.env.HOT_UPDATER_SUPABASE_BUCKET_NAME!,
}),
database: supabaseDatabase({
supabaseUrl: process.env.HOT_UPDATER_SUPABASE_URL!,
supabaseAnonKey: process.env.HOT_UPDATER_SUPABASE_ANON_KEY!,
}),
});
/*
후: storage만 firebase로 갈아 낀 모습
storage: firebase
DB: supabase
*/
import { supabaseDatabase } from "@hot-updater/supabase";
import { firebaseStorage } from "@hot-updater/firebase";
export default defineConfig({
build: metro({
enableHermes: true,
}),
storage: firebaseStorage({
apiKey: process.env.HOT_UPDATER_FIREBASE_API_KEY;
projectId: process.env.HOT_UPDATER_FIREBASE_PROJECT_ID;
storageBucket: process.env.HOT_UPDATER_FIREBASE_STORAGE_BUCKET;
}),
database: supabaseDatabase({
supabaseUrl: process.env.HOT_UPDATER_SUPABASE_URL!,
supabaseAnonKey: process.env.HOT_UPDATER_SUPABASE_ANON_KEY!,
}),
});

해치웠나????????

해치웠다(1/4)
프로젝트 구조 이해 했고, 모노 레포도 익숙해졌으니 개발에 속도가 좀 나지 않을까 생각한다.