Skip to content

Commit f2a0b54

Browse files
authored
Merge pull request #34 from inokawa/preact
Add Preact support
2 parents dcbac4b + 69cd6ea commit f2a0b54

File tree

9 files changed

+97
-35
lines changed

9 files changed

+97
-35
lines changed

README.md

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
![npm](https://img.shields.io/npm/v/react-native-react-bridge) ![check](https://github.com/inokawa/react-native-react-bridge/workflows/check/badge.svg)
44

5-
An easy way to integrate your [React](https://github.com/facebook/react) app into [React Native](https://github.com/facebook/react-native) app with WebView.
5+
An easy way to integrate your [React](https://github.com/facebook/react) (or [Preact](https://github.com/preactjs/preact)) app into [React Native](https://github.com/facebook/react-native) app with WebView.
66

77
## Why?
88

@@ -21,7 +21,7 @@ The communication between React app and React Native app will be also simplified
2121

2222
## Features
2323

24-
- Create React app bundle for WebView automatically in build process of React Native
24+
- Create React (or Preact) app bundle for WebView automatically in build process of React Native
2525
- `.js`, `.ts`, `.jsx`, `.tsx` and `.mjs` will be packed into one source.
2626
- NOTE: Only the edits in the entry file of web will invoke rebuild because of the limitation of [metro](https://github.com/facebook/metro)'s build process.
2727
- Handle communication between React Native and WebView with React hook style
@@ -41,16 +41,20 @@ If you have some feature requests or improvements, please create a [issue](https
4141
## Install
4242

4343
```sh
44-
npm install react-native-react-bridge
44+
npm install react-native-react-bridge react-native-webview
4545

46-
# These are used to render React app in WebView
47-
npm install react-dom react-native-webview
46+
# Necessary only if you render React app in WebView
47+
npm install react-dom
48+
49+
# Necessary only if you render Preact app in WebView
50+
npm install preact
4851
```
4952

5053
### Requirements
5154

52-
- react 16.8+
53-
- react-native 0.60+
55+
- react >= 16.8
56+
- react-native >= 0.60
57+
- (preact >= 10.0)
5458

5559
## Usage
5660

@@ -68,7 +72,10 @@ module.exports = {
6872
};
6973
```
7074

71-
2. Make entry file for React app.
75+
2. Make entry file for web app.
76+
77+
- If you use React in web, import modules from `react-native-react-bridge/lib/web` and `react`.
78+
- If you use Preact in web, import modules from `react-native-react-bridge/lib/web/preact` and `preact`.
7279

7380
```jsx
7481
// WebApp.js

package-lock.json

Lines changed: 17 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "react-native-react-bridge",
33
"version": "0.4.3",
4-
"description": "An easy way to integrate your React app into React Native app with WebView.",
4+
"description": "An easy way to integrate your React (or Preact) app into React Native app with WebView.",
55
"main": "lib/index.js",
66
"module": "lib/index.mjs",
77
"types": "lib/index.d.ts",
@@ -26,6 +26,7 @@
2626
"babel-jest": "26.6.3",
2727
"jest": "26.6.3",
2828
"metro-react-native-babel-preset": "0.65.0",
29+
"preact": "10.5.13",
2930
"react": "16.13.1",
3031
"react-dom": "16.13.1",
3132
"react-native": "0.63.4",
@@ -46,9 +47,10 @@
4647
"url": "git+https://github.com/inokawa/react-native-react-bridge.git"
4748
},
4849
"keywords": [
49-
"react",
5050
"react-native",
51+
"react",
5152
"react-dom",
53+
"preact",
5254
"metro",
5355
"webview",
5456
"html",

rollup.config.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,20 @@ export default [
3434
],
3535
plugins: [typescript()],
3636
},
37+
{
38+
input: "src/web/preact.ts",
39+
output: [
40+
{
41+
file: `${mainDir}/web/preact.js`,
42+
format: "cjs",
43+
},
44+
{
45+
file: `${moduleDir}/web/preact.mjs`,
46+
format: "es",
47+
},
48+
],
49+
plugins: [typescript()],
50+
},
3751
{
3852
input: "src/plugin/index.js",
3953
output: [

src/plugin/__snapshots__/metro.spec.js.snap

Lines changed: 8 additions & 8 deletions
Large diffs are not rendered by default.

src/web/bridge.ts

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,32 @@
1-
import React, { useEffect } from "react";
2-
import ReactDOM from "react-dom";
31
import { EVENT_KEY, ROOT_ID } from "../common";
42
import { Message } from "../types";
53

6-
export const webViewRender = (root: JSX.Element): string => {
7-
ReactDOM.render(root, document.getElementById(ROOT_ID));
8-
return ""; // dummy
4+
export const buildRender = <T extends (a: any, b: HTMLElement) => void>(
5+
render: T
6+
) => {
7+
return (root: Parameters<T>[0]): string => {
8+
render(root, document.getElementById(ROOT_ID)!);
9+
return ""; // dummy
10+
};
911
};
1012

1113
export const emit = <T>(message: Message<T>) => {
1214
(window as any).ReactNativeWebView.postMessage(JSON.stringify(message));
1315
};
1416

15-
export const useSubscribe = <T>(onSubscribe: (message: Message<T>) => void) => {
16-
useEffect(() => {
17-
const listener = (e: any) => {
18-
if (!isMessageEvent<T>(e)) return;
19-
onSubscribe({ type: e.detail.type, data: e.detail.data });
20-
};
21-
window.addEventListener(EVENT_KEY, listener);
22-
return () => {
23-
window.removeEventListener(EVENT_KEY, listener);
24-
};
25-
}, [onSubscribe]);
17+
export const buildUseSubscribe = (useEffect: any) => {
18+
return <T>(onSubscribe: (message: Message<T>) => void) => {
19+
useEffect(() => {
20+
const listener = (e: any) => {
21+
if (!isMessageEvent<T>(e)) return;
22+
onSubscribe({ type: e.detail.type, data: e.detail.data });
23+
};
24+
window.addEventListener(EVENT_KEY, listener);
25+
return () => {
26+
window.removeEventListener(EVENT_KEY, listener);
27+
};
28+
}, [onSubscribe]);
29+
};
2630
};
2731

2832
const isMessageEvent = <T>(e: any): e is { detail: Message<T> } =>

src/web/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export { webViewRender, emit, useSubscribe } from "./bridge";
1+
export { webViewRender, emit, useSubscribe } from "./react";

src/web/preact.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { useEffect } from "preact/compat";
2+
import { render } from "preact";
3+
import { buildRender, buildUseSubscribe } from "./bridge";
4+
5+
export const webViewRender = buildRender(render);
6+
7+
export { emit } from "./bridge";
8+
9+
export const useSubscribe = buildUseSubscribe(useEffect);

src/web/react.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { useEffect } from "react";
2+
import { render } from "react-dom";
3+
import { buildRender, buildUseSubscribe } from "./bridge";
4+
5+
export const webViewRender = buildRender(render);
6+
7+
export { emit } from "./bridge";
8+
9+
export const useSubscribe = buildUseSubscribe(useEffect);

0 commit comments

Comments
 (0)