{"id":34730186,"url":"https://github.com/fe-dudu/expo-webview-kit","last_synced_at":"2026-04-13T13:31:36.492Z","repository":{"id":283943539,"uuid":"952429392","full_name":"fe-dudu/expo-webview-kit","owner":"fe-dudu","description":"All-in-one tools for expo webview development","archived":false,"fork":false,"pushed_at":"2025-05-03T15:48:59.000Z","size":791,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-03T16:48:55.292Z","etag":null,"topics":["design-system","expo","expo53","jotai","lucide-react","react-native","react-router","react19","shadcn-ui","storybook","suspensive","tailwind","tansack-query"],"latest_commit_sha":null,"homepage":"https://fe-dudu.github.io/expo-webview-kit","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fe-dudu.png","metadata":{"files":{"readme":"README.ko.md","changelog":"changelog-template.hbs","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-03-21T09:10:48.000Z","updated_at":"2025-05-03T15:49:01.000Z","dependencies_parsed_at":"2025-03-23T08:20:31.228Z","dependency_job_id":"239ea8be-732e-4e53-9748-16cc85005823","html_url":"https://github.com/fe-dudu/expo-webview-kit","commit_stats":null,"previous_names":["fe-dudu/expo-webview-kit"],"tags_count":0,"template":true,"template_full_name":null,"purl":"pkg:github/fe-dudu/expo-webview-kit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fe-dudu%2Fexpo-webview-kit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fe-dudu%2Fexpo-webview-kit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fe-dudu%2Fexpo-webview-kit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fe-dudu%2Fexpo-webview-kit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fe-dudu","download_url":"https://codeload.github.com/fe-dudu/expo-webview-kit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fe-dudu%2Fexpo-webview-kit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31754807,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-13T13:27:56.013Z","status":"ssl_error","status_checked_at":"2026-04-13T13:21:23.512Z","response_time":93,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["design-system","expo","expo53","jotai","lucide-react","react-native","react-router","react19","shadcn-ui","storybook","suspensive","tailwind","tansack-query"],"created_at":"2025-12-25T02:56:27.450Z","updated_at":"2026-04-13T13:31:36.478Z","avatar_url":"https://github.com/fe-dudu.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"## 1️⃣ 프로젝트 관리\n**monorepo**에 맞는 **Trunk based development** 전략을 사용하며 (Main branch만 허용) Main branch에 Merge될 때마다 dev 환경에 배포합니다.\n\n필요에 따라 test, prod 환경에 배포 및 release version을 추가합니다.\n\n## 2️⃣ 프로젝트 버전 관리\n**auto-changelog** library로 Changelog를 자동 생성하여 version 별 commit history를 관리합니다.\n\n**Git tag**로 release version을 관리합니다.\n\n## 3️⃣ 파일 관리\n- `knip`을 사용하여 사용되지 않는 파일 및 코드를 정리합니다.\n- 재사용 가능성이 충분히 검증되지 않은 상태에서 성급한 추상화를 하지 않습니다.\n- 중복을 줄이는 것보다 유지보수성을 고려하여 적절한 중복을 허용합니다.\n- 중복되지 않는 컴포넌트, 훅, 유틸 함수는 각각 pages에서 관리하여 수정 및 삭제를 용이하게 합니다.\n- 동일한 기능이 여러 곳에서 사용되고 유지보수 측면에서 이점이 있는 경우에만 공통 폴더로 분리합니다.\n\n## 4️⃣ 라이브러리 버전 관리\n**pnpm catalog** 기능으로 모노레포 통합 라이브러리 버전을 관리합니다.\n\n## 5️⃣ 코드 스타일 및 린트 규칙\n본 프로젝트에서는 코드 일관성을 유지하고 코드 품질을 보장하기 위해 `commitlint`와 `Biome`를 사용하여 lint를 수행하고 `TypeScript`를 통해 타입을 검사합니다.\n\n### 1. 커밋 메시지 규칙 (`commitlint`)\n`commitlint`를 사용하여 커밋 메시지가 [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) 형식을 따르도록 강제합니다.\n\n#### 1-1. 커밋 메시지 형식\n`\u003c타입\u003e(\u003c스코프\u003e): \u003c변경 사항 요약\u003e`\n\n#### 1-2. 타입\n| 타입  | 설명 |\n|------|------|\n| `feat`  | 새로운 기능 추가 |\n| `fix`  | 버그 수정 |\n| `perf`  | 성능을 개선하는 코드 변경 |\n| `refactor`  | 기능 추가나 버그 수정이 아닌 코드 개선 |\n| `style`  | 영향을 주지 않는 스타일 변경 (공백, 포맷팅, 오타, 세미콜론 등) |\n| `test`  | 누락된 테스트 추가 또는 기존 테스트 수정 |\n| `docs`  | 문서 추가/수정 |\n| `chore`  | 유지보수 작업 (라이브러리 업데이트, 파일 이동 등) |\n\n\n#### 1-3. 스코프\n모노레포에서는 여러 패키지와 모듈이 하나의 저장소에 포함되기 때문에, **커밋 메시지**만으로 어떤 부분이 변경되었는지 파악하기 어렵습니다.\n\n따라서 `scope-empty: [2, 'never']` 규칙을 적용하여 **스코프를 반드시 명시**해야 합니다.\n\n| 스코프 | 설명 |\n|--------|------|\n| `*` | 저장소 전체에 영향을 주는 변경 |\n| `mobile` | 모바일 애플리케이션 관련 변경 |\n| `web` | 웹 애플리케이션 관련 변경 |\n| `admin` | 관리자 페이지 관련 변경 |\n| `api` | API 관련 변경 |\n| `tanstack-query` | Tanstack Query 설정 변경 |\n| `tsconfig` | TypeScript 설정 변경 |\n| `ui` | UI 컴포넌트 및 디자인 시스템 관련 변경 |\n| `utils` | 공통 유틸리티 함수 변경 |\n\n\u003e **예시**\n\u003e - feat(auth): 로그인 기능 추가\n\u003e - fix(api): 응답 데이터 형식 수정\n\n### 2. 코드 린트 규칙 (`Biome`)\n\n`Biome`를 사용하여 코드 스타일, 접근성, 복잡성 등을 검사하며 기본 설정 외에 추가한 규칙은 아래와 같습니다.\n\n#### 2-1. 복잡성 (`complexity`)\n| 규칙 | 설명 |\n|------|------|\n| `noVoid` | `void` 연산자의 사용을 금지 |\n| `noBannedTypes` | 금지된 타입 사용 방지 |\n| `noExtraBooleanCast` | 불필요한 불리언 변환 방지 (`!!`) |\n| `noExcessiveCognitiveComplexity` | 지나치게 복잡한 코드 방지 |\n\n#### 2-2. 코드 정확성 (`correctness`)\n| 규칙 | 설명 |\n|------|------|\n| `noUnusedImports` | 사용하지 않는 import 금지 |\n| `noUnusedVariables` | 사용되지 않는 변수 금지 |\n| `useArrayLiterals` | 배열 선언 시 `Array()` 대신 `[]` 사용 |\n| `useHookAtTopLevel` | React 훅을 최상위에서만 사용하도록 강제 |\n\n#### 2-3. 실험적 규칙 (`nursery`)\n| 규칙 | 설명 |\n|------|------|\n| `useAtIndex` | 배열 요소 접근 시 `arr.at(index)` 사용 권장 |\n| `useGuardForIn` | `for...in` 사용 시 `hasOwnProperty` 검사 강제 |\n| `useCollapsedIf` | `if` 중첩을 줄여 가독성 개선 |\n| `useConsistentCurlyBraces` | 중괄호 `{}` 사용 방식 일관성 유지 |\n| `noSubstr` | `string.substr()` 사용 금지 |\n| `noCommonJs` | CommonJS(`require`) 대신 ESM(`import`) 사용 |\n| `noNestedTernary` | 중첩 삼항 연산자 사용 금지 |\n| `noDocumentCookie` | `document.cookie` 사용 금지 |\n| `noExportedImports` | 다시 export할 import 금지 |\n| `noUnknownPseudoClass` | 잘못된 CSS 의사 클래스 사용 금지 |\n| `noUnknownTypeSelector` | 알 수 없는 CSS 타입 선택자 사용 금지 |\n\n#### 2-4. 성능 (`performance`)\n| 규칙 | 설명 |\n|------|------|\n| `noBarrelFile` | 배럴 파일(index.ts) 사용 금지 |\n| `noReExportAll` | `export * from` 사용 금지 |\n| `noDelete` | `delete` 연산자 사용 금지 |\n\n#### 2-5. 보안 (`security`)\n| 규칙 | 설명 |\n|------|------|\n| `noDangerouslySetInnerHtml` | React의 `dangerouslySetInnerHTML` 사용 금지 |\n\n#### 2-6. 스타일 (`style`)\n| 규칙 | 설명 |\n|------|------|\n| `noUselessElse` | 불필요한 `else` 문 제거 |\n| `useCollapsedElseIf` | `else if`를 `if`로 변경 가능하면 변경 |\n| `noNonNullAssertion` | `!`(non-null assertion) 사용 금지 |\n| `useShorthandArrayType` | `Array\u003cT\u003e` 대신 `T[]` 사용 |\n| `useBlockStatements` | 단일 구문이라도 `{}` 사용 강제 |\n| `noNamespace` | TypeScript `namespace` 사용 금지 |\n| `noYodaExpression` | `if (42 === x)` 형태의 요다 조건문 금지 |\n| `useConsistentBuiltinInstantiation` | `new Array()` 대신 `[]` 사용 |\n| `useDefaultSwitchClause` | `switch` 문에 `default` 케이스 추가 필수 |\n| `useFragmentSyntax` | `\u003cReact.Fragment\u003e` 대신 `\u003c\u003e` 사용 |\n| `useThrowNewError` | `throw new Error()` 필수 |\n| `useThrowOnlyError` | `throw`는 `Error` 객체만 허용 |\n| `useFilenamingConvention` | 파일명은 `camelCase` 또는 `PascalCase` |\n\n#### 2-7. 의심스러운 코드 (`suspicious`)\n| 규칙 | 설명 |\n|------|------|\n| `noArrayIndexKey` | React `key`로 배열 인덱스 사용 금지 |\n| `noAssignInExpressions` | 할당문(`=`)을 조건문 내에서 사용 금지 |\n| `noConfusingVoidType` | `void` 타입 혼란 방지 |\n| `noConsole` | `console` 사용 금지 |\n| `noDebugger` | `debugger` 사용 금지 |\n| `noExplicitAny` | `any` 타입 사용 금지 |\n| `noRedeclare` | 동일한 변수 재선언 금지 |\n\n## 6️⃣ 상태 관리 전략\n\n#### 1. 동기 상태 (Synchronous State)\n- **Jotai**를 사용하여 상태를 관리합니다. **Jotai**는 Atomic 상태 관리를 제공하며 각 상태를 개별적으로 관리할 수 있어 필요에 따라 상태를 업데이트하고 종속된 상태만 변경할 수 있는 유연성을 제공합니다.\n- 동기 상태는 하향식 (top-down) 관리가 아니라 상향식 (bottom-up) 방식으로 관리되며 이는 각 상태가 독립적으로 존재하고 다른 상태들에 영향을 받지 않기 때문에 효율적으로 상태를 쌓아 올릴 수 있습니다.\n\n#### 2. 비동기 상태 (Asynchronous State)\n- 성공, 실패, 대기, 취소, 경쟁, 비어있음 등 여러 비동기 상태를 관리할 때 직접적으로 모든 상태를 store에 구현하지 않고 **Tanstack Query**가 제공하는 훅을 통해 관리합니다.\n\n## 7️⃣ 컴포넌트 관리\n\n#### 1. Domain 컴포넌트 (apps/*/components)\n- 도메인 로직을 포함한 컴포넌트로 비즈니스 로직과 API 응답에 강하게 결합되어 있습니다.\n- API에서 받은 데이터를 상태로 관리하며 비즈니스 로직을 처리합니다. 예를 들어, API 응답 데이터를 변형하거나 계산하는 등의 작업을 합니다.\n- 외부 서비스나 API와의 통신을 담당하며 다른 컴포넌트에서 이를 호출하여 데이터를 사용할 수 있습니다.\n\n#### 2. UI 컴포넌트 (packages/ui)\n- 도메인과 분리된 상태로 데이터를 받아 보여주는 역할만을 합니다.\n- 필요한 데이터는 부모 컴포넌트로부터 props로 전달받습니다.\n- 레이아웃, 스타일, 상호작용 등 UI 요소를 정의하며, 데이터를 시각적으로 표현하는 데 집중합니다.\n\n#### 3. 내부 선언 순서\n1. useRef\n2. useState\n3. customHook\n4. derived state\n5. useMemo\n5. function(useCallback)\n6. useEffect\n\n#### 4. 외부 선언 규칙\n상수는 컴포넌트 외부에 선언합니다.\n```\nconst MAX_ITEMS = 10;\nexport function Component() {\n  return \u003cdiv\u003e...\u003c/div\u003e;\n}\n```\n\n## 8️⃣ 장애 허용성\nFrontend는 사용자의 네트워크 환경, API 서버 장애, API 응답 데이터 등 다양한 외부 환경에 영향을 받습니다.\n\n외부 혹은 내부에 장애가 발생하더라도 시스템이 완전히 멈추지 않고 사용자에게 적절한 피드백을 제공하여 앱이 계속해서 작동하도록 소프트웨어를 개발해야 합니다.\n\n#### 1. 느린 사용자 네트워크 환경\n- 로딩 스피너, 스켈레톤 UI를 제공하여 명확하게 대기 상태임을 인지시킬 수 있어야 합니다.\n\u003e API 응답이 빠를 경우 (250ms 이하) 로딩 스피너, 스켈레톤 UI가 불필요할 수 있으므로 로딩 스피너, 스켈레톤 UI에 Delay를 주는 것이 좋습니다.\n\u003e\n\u003e 불필요한 Layout shift 혹은 깜빡임이 생기지 않도록 주의해야 합니다.\n\n#### 2. 일시적인 사용자 네트워크 끊김\n- 네트워크가 끊길 경우 재시도 간격을 점차 늘려가며 요청을 다시 보냅니다. (지수 백오프)\n- 네트워크가 끊겼다가 다시 연결될 경우 요청을 다시 보냅니다.\n- 에러 경계(ErrorBoundary) 처리하여 장애가 발생한 부분을 제외하고 계속해서 앱이 작동하도록 합니다.\n- 사용자가 네트워크 연결이 끊길 경우 Toast message로 다시 네트워크에 연결하도록 요청합니다.\n\n#### 3. API 서버 장애\n- API 요청이 실패할 경우 재시도 간격을 점차 늘려가며 요청을 다시 보냅니다. (지수 백오프)\n- 에러 경계(ErrorBoundary) 처리하여 장애가 발생한 부분을 제외하고 계속해서 앱이 작동하도록 합니다.\n\n#### 4. 런타임에 API 응답 데이터 에러\n- 에러 경계(ErrorBoundary) 처리하여 장애가 발생한 부분을 제외하고 계속해서 앱이 작동하도록 합니다.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffe-dudu%2Fexpo-webview-kit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffe-dudu%2Fexpo-webview-kit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffe-dudu%2Fexpo-webview-kit/lists"}