gronxb / webview-bridge

Fully Type-Safe Integration for React Native WebView and Web
https://gronxb.github.io/webview-bridge/
MIT License
222 stars 5 forks source link

web에서 타입 문제 #39

Closed 11t518s closed 6 months ago

11t518s commented 6 months ago

우선 한국어가 가능하신 듯 하여 한국어로 질문드립니다. If you are not familiar with Korean, please let me know. I will register the issue again in English.

안녕하세요 최근에 새로은 프로젝트를 시작하면서 해당 라이브러리를 사용해보려하고 있습니다. (1.4.1 최신버전을 사용하려 했습니다.)

그런데 동작은 잘 되지만 사용할 때 제대로 타입 추론이 안돼서 질문드립니다.

  1. linkBridge 타입 추론 image

    a. 우선 공식문서에 나온대로 설정을 완료했으나 타입이 제대로 추론안되는지 사진과 같은 error가 나옵니다.

b. 추론되는 타입도 AppBridge에서 추론된 타입이 메서드로 등록돼야할 것 같은데, AppBridge의 return type도 BridgeStore로 연결되는 듯 해서 혹 이부분에 대해 제가 어떻게 해보면 좋을 지 의견 구합니다!

  1. useBridgeStore 타입 추론 image

    a. 이 메서드도 마찬가지로 error가 등장합니다. 이 친구는 제네릭 때문인 것 같긴한데 혹 해결할 방법있을까요?

감사합니다!

gronxb commented 6 months ago

안녕하세요 !

현재 프로젝트가 모노레포 구조일까요 ? react native 프로젝트에서 AppBridge 타입을 내보내고, 웹쪽 프로젝트에서 가져오는 부분이 제일 중요합니다. 아래 코드와 같이 react-native 프로젝트에서 내보낸 다음, web 프로젝트에서 import 해야합니다. https://github.com/gronxb/webview-bridge/blob/main/example/react-navigation/react-native/src/bridge.ts#L62

react native 측에서 AppBridge를 어떻게 내보냈는지 제가 확인할 수 있다면 도움을 더 쉽게 드릴 수 있을 것 같습니다 !

모노레포 구조가 아니라면 https://gronxb.github.io/webview-bridge/exporting-type-declarations/custom-declaration-file.html 해당 페이지에서 정적으로 타입을 만들어서 내보내야합니다.

gronxb commented 6 months ago

혹시나 타입을 내보낼 수 없어서 직접 정의해야한다면, 다음 코드베이스를 참고해보세요.

"use client";
import { createLinkBridgeProvider } from "@webview-bridge/react";
import type { Bridge, BridgeStore } from "@webview-bridge/web";

interface BridgeState extends Bridge {
  count: number;
  increment: () => Promise<void>;
}

type AppBridge = BridgeStore<BridgeState>;

export const {
  BridgeProvider,
  useBridgeStatus,
  useBridgeLoose,
  useBridgeStore,
} = createLinkBridgeProvider<AppBridge>({
  throwOnError: true,
  onReady: () => {
    console.log("nativeMethod is ready");
  },
});
11t518s commented 6 months ago

https://github.com/daehwahap/monorepo/tree/feat/webview-bridge

안녕하세요! 위의 링크는 작업중인 브랜치 입니다.

https://github.com/daehwahap/monorepo/blob/feat/webview-bridge/apps/app/src/AppPostMessageBridge/index.ts#L22 여기서 export 해주고 있고

https://github.com/daehwahap/monorepo/blob/feat/webview-bridge/apps/webview/WebPostMessageBridge/index.ts#L5 여기서 사용하고 있습니다!

보통 이런상황에서는 제가 간단하고 사소한 무언가를 놓치고있는 것 같던데, 한번만 확인해주시면 감사하겠습니다!

gronxb commented 6 months ago

첫번째로 shared state를 사용하지 않는 경우 있는 그대로의 타입 추론을 위해 get,set callback을 지워야합니다.

해당 get,set callback을 사용해서 shared state를 사용할 경우 내부에서는 타입 추론이 힘들기 때문에, 외부에서 인터페이스를 정의해야합니다. (zustand store 선언할 때와 동일합니다.) Shared State 인터페이스 정의

현재 코드에서는 shared state를 사용하고 있는 흔적이 없기 때문에, 콜백만 지웠습니다.

--- a/apps/app/src/AppPostMessageBridge/index.ts
+++ b/apps/app/src/AppPostMessageBridge/index.ts
@@ -1,7 +1,7 @@
 import {bridge, createWebView} from '@webview-bridge/react-native';

 // Register functions in the bridge object in your React Native code
-export const appBridge = bridge(({get, set}) => ({
+export const appBridge = bridge({
   async getMessage() {
     return "Hello, I'm native";
   },
@@ -9,7 +9,7 @@ export const appBridge = bridge(({get, set}) => ({
     console.log(data);
     return 'aaaaaa';
   },
-}));
+});

 export const {WebView} = createWebView({
   bridge: appBridge,
@@ -20,4 +20,3 @@ export const {WebView} = createWebView({
 });

 export type AppBridge = typeof appBridge;

두번째로 base.json에 있는

"declaration": true,
"declarationMap": true,

해당 필드들이 default로 들어가기 때문입니다. next.js의 경우 배포할 때 d.ts를 내보내지 않으므로, false로 맞춰주셔야합니다 ! base.json에서 해당 필드를 지우거나, 아래와 같이 apps/webviewtsconfig.json을 설정한다면 해결됩니다.

--- a/apps/webview/tsconfig.json
+++ b/apps/webview/tsconfig.json
@@ -5,7 +5,9 @@
       {
         "name": "next"
       }
-    ]
+    ],
+    "declaration": false,
+    "declarationMap": false
   },
   "include": [
     "next-env.d.ts",

감사합니다 !

11t518s commented 6 months ago
image

오 말씀해주신대로 적용하니까 이제 추론 잘 됩니다!

좋은 라이브러리 만들어주셔서 감사하고 사용하면서 혹시 제가 기여할 수 있는 부분이 생기면 기여해보겠습니다!

이번 이슈는 제작자님 께서 닫아주시면 감사하겠습니다!