mn-super-app
v2.0.6
Published
Thư viện React Native dùng để bọc mini app khi chạy bên trong super app.
Readme
mn-super-app
mn-super-app là thư viện React Native dùng để đóng gói một mini app khi chạy bên trong host super app. Thư viện cung cấp:
- Một wrapper UI hiển thị nút kéo thả nổi và nút quay về host app.
- Hai hành động chủ động
CậpvàNạpđể mini app tự cập nhật bundle mới hoặc tự reload tại chỗ. - Một hành động
Set Mainđể mini app tự đặt chính nó làm bundle chính của super app khi được cho phép. - Hỗ trợ chế độ mini app đang là bundle chính của super app thông qua prop
isMainAppBundle. - Một HOC
miniapp()để namespace dữ liệuAsyncStoragetheoappIdvàappName. - Một component mặc định
SuperAppđể bật hoặc tắt chế độ mini app thông qua propappType.
Tài liệu liên quan
Quy ước dự án
- Tất cả tài liệu, comment và nội dung văn bản trong repo phải viết bằng tiếng Việt có dấu.
- Mọi hàm trong repo phải có comment JSDoc đặt ngay phía trên hàm.
- Rule cục bộ của repo được khai báo tại AGENTS.md.
Tổng quan hoạt động
Khi appType === "miniapp", thư viện sẽ:
- Render
childrenbên trong một container toàn màn hình. - Hiển thị floating action có thể kéo thả.
- Cho phép bấm
Cậpđể tải bundle mới nhất rồi remount mini app ngay tại chỗ. - Cho phép bấm
Nạpđể reload lại mini app bằng bundle local hiện có hoặc bundle fallback mà host truyền xuống. - Tự động hút floating action về mép trái hoặc mép phải khi thả tay.
- Gọi
NativeModules.ConnectNativeModule.closeApp(appName)khi bấm nút home.
Khi isMainAppBundle === true, floating action sẽ chuyển sang chế độ thao tác main runtime:
- Ẩn nút home vì mini app không còn chạy trong
MiniAppActivity. - Nút
Cậpgọi flow cập nhật dành riêng cho bundle chính của host. - Nút
Nạpreload lại runtime chính của host theo startup bundle hiện tại. - Hiển thị thêm nút
Unsetđể huỷ trạng thái app chính và quay lại bundle gốc của super app. - Khi host vừa gọi
setMainAppBundle(...):- iOS sẽ đóng miniapp hiện tại, quay về màn hình chính rồi reload theo bundle mới.
- Android sẽ quay về
MainActivityvà reload lại host theo bundle mới mà không cần tự thoát app.
Khi appType khác "miniapp", component chỉ render children và không thêm UI hoặc hành vi native.
Khi isMainAppBundle !== true và allowSetMain === true, floating action có thể hiển thị thêm nút Set Main để gọi setMainAppBundle(...).
Khi người dùng bấm nút Set Main trên floating action, thư viện sẽ hiển thị thông báo xác nhận để người dùng biết app sắp đổi bundle chính.
Khi isShowMenuSetMain === true và mini app đủ điều kiện đặt làm app chính, thư viện tự hiển thị action sheet sau 7 giây để người dùng chọn:
Đặt làm app chính: thực hiện set main ngay.Không nhắc lại: lưu lựa chọn theoappIdvà không tự hiển thị gợi ý ở những lần khởi động sau.Để sau: đóng gợi ý và vẫn hiển thị lại ở lần khởi động tiếp theo.
Yêu cầu tích hợp
- React Native
0.72.4theopackage.json. - Host app cần expose native module
ConnectNativeModulevới hàmcloseApp(appName). - Nếu muốn dùng nút
CậpvàNạp, host app cần expose thêmreloadApp(...)vàupdateAndReloadApp(...). - Nếu muốn dùng nút
Set Main, host app cần expose thêmsetMainAppBundle(bundleName, appId, bundleUrl, initProps). - Nếu muốn hỗ trợ mini app đang là app chính, host app cần expose thêm:
updateCurrentMainAppBundle(bundleUrl, initProps)reloadCurrentMainAppBundle(initProps)unsetCurrentMainAppBundle()
- Host app cũng cần tự xử lý UX sau
setMainAppBundle(...)theo platform:- iOS: quay về màn hình chính và reload host.
- Android: quay về
MainActivityvà tạo lại host runtime bằng bundle mới.
- Mini app cần chấp nhận cơ chế prefix key trong
AsyncStoragetrong vòng đời component được wrap bởiminiapp().
Cài đặt
Nếu package được sử dụng nội bộ, có thể cài đặt từ registry hoặc từ source:
npm install mn-super-appHoặc với repo local:
npm install /path/to/mn-super-appCách dùng nhanh
1. Wrap màn hình mini app
import React from "react";
import { View, Text } from "react-native";
import { miniapp } from "mn-super-app";
function DemoScreen() {
return (
<View>
<Text>Hello mini app</Text>
</View>
);
}
export default miniapp(DemoScreen, {
appId: "demo",
appName: "hello-app",
allowSetMain: true,
});2. Render từ host
<DemoScreen appType="miniapp" />Nếu không truyền appType="miniapp", component vẫn render bình thường như một màn hình React Native thông thường.
Hành vi floating action theo runtime
Mini app thường
Set Main: gọisetMainAppBundle(...)nếuallowSetMain === true- Khi bấm
Set Maintrên floating action, thư viện hiện hộp thoại xác nhận trước khi gọi native - Khi
isShowMenuSetMain === true, action sheet gợi ý set main sẽ xuất hiện sau 7 giây nếu app chưa là main và người dùng chưa chọnKhông nhắc lại - iOS: sau khi xác nhận, mini app sẽ quay về màn hình chính và host tự reload theo bundle mới
- Android: sau khi xác nhận, app sẽ quay về
MainActivityvà host tự nạp lại bundle mới Cập: gọiupdateAndReloadApp(...)Nạp: gọireloadApp(...)Home: gọicloseApp(...)
Mini app đang là app chính
Cập: gọiupdateCurrentMainAppBundle(bundleUrl, initProps)Nạp: gọireloadCurrentMainAppBundle(initProps)Unset: gọiunsetCurrentMainAppBundle()- Không hiển thị nút
Home - Sau
Cập, host phải tiếp tục giữisMainAppBundle === truecho cùng mini app nếu update thành công
API
default export SuperApp
Component wrapper nhận các props sau:
| Prop | Bắt buộc | Mô tả |
| --- | --- | --- |
| appType | Không | Khi bằng "miniapp" sẽ bật giao diện nổi và hành vi native. |
| appName | Có trong mini app mode | Tên app được truyền vào native module khi đóng app. |
| isDevBundle | Không | Cờ cho biết mini app đang chạy bằng Metro dev bundle hay production bundle. |
| isMainAppBundle | Không | Khi bằng true, thư viện sẽ đổi hành vi Cập và Nạp sang main runtime và ẩn nút home. |
| allowSetMain | Không | Khi bằng true và mini app chưa là main, thư viện có thể hiển thị action Set Main. |
| isShowMenuSetMain | Không | Khi bằng true, tự động mở gợi ý đặt app chính sau 7 giây nếu app đủ điều kiện. |
| children | Có | Nội dung màn hình cần render. |
miniapp(WrappedComponent, config)
Higher-order component để wrap một màn hình mini app.
config gồm:
| Trường | Bắt buộc | Mô tả |
| --- | --- | --- |
| appId | Có | Prefix phân vùng dữ liệu lưu trữ. |
| appName | Có | Prefix phân vùng dữ liệu lưu trữ và tên app gửi cho native host. |
| allowSetMain | Không | Mặc định là true, cho phép hiển thị action Set Main khi mini app chưa là app chính. |
| isShowMenuSetMain | Không | Mặc định là false, cho phép tự động mở gợi ý đặt app chính sau 7 giây. Có thể override bằng runtime prop cùng tên. |
HOC sẽ:
- Override
AsyncStorage.getItemvàAsyncStorage.setItem. - Thêm prefix key theo format
${appId}_${appName}_${key}. - Khôi phục lại implementation gốc khi component unmount.
- Truyền
allowSetMainxuốngSuperAppvàWrappedComponentđể UI hoặc màn hình miniapp có thể biết quyền hiển thị actionSet Main.
Hành vi AsyncStorage
Khi một component được wrap bằng miniapp(), mọi lệnh:
AsyncStorage.getItem("token")
AsyncStorage.setItem("token", value)sẽ được chuyển thành:
AsyncStorage.getItem(`${appId}_${appName}_token`)
AsyncStorage.setItem(`${appId}_${appName}_token`, value)Điều này giúp tách dữ liệu giữa nhiều mini app dùng chung một host.
Cấu trúc repo
.
|-- AGENTS.md
|-- README.md
|-- docs/
|-- home.png
|-- index.js
|-- move.png
`-- package.jsonScripts
npm run packLệnh này tạo gói .tgz để kiểm thử hoặc phát hành package nội bộ bằng npm pack.
Lưu ý khi bảo trì
- Thư viện hiện tại can thiệp
AsyncStorageở mức global trong thời gian mini app được mount. Nếu nhiều mini app cùng chạy song song, cần kiểm tra kỹ tác động chồng chéo. - Mã nguồn hiện đã dùng
@react-native-async-storage/async-storageđể khớp với dependency khai báo trongpackage.json. - Package chưa có test tự động.
Phát triển
npm install
npm run packRepo hiện là một package library nhỏ, chưa có ứng dụng demo hoặc pipeline test đi kèm.
