如何用TypeScript、React和Vite导入Cordova插件?



我有一个用Vite构建的TypeScript React项目。这是一个Ionic React项目,我为Android和iOS构建应用程序,以及为web构建PWA。

我试图在我的应用程序中使用最新版本(13)的cordova-purchase-plugin。这个版本添加了TypeScript支持,但它不是一个模块,所以我很困惑如何正确输入它(我导入的应用程序中的其他所有内容都是一个模块)。

一个非常简单的代码示例:

import 'cordova-plugin-purchase';
const store = new CdvPurchase.Store();

当我在Vite中构建它时,它编译时没有错误。在VSCode中,我可以操作store对象,并且插件的内置类型被正确显示。

但是,当我在web浏览器中打开PWA时,我得到一个错误:

找不到变量:CdvPurchase

所以导入失败了。

cordova-plugin-purchase包含一个单独的JS文件store.js

为了让我编译的应用程序加载,我可以将这个store.js文件复制到我的应用程序的资产目录中,然后通过index.html中的<script>标签添加它。这将CdvPurchase置于全局作用域,并允许我的应用程序加载。然而,我显然不想手动地将脚本从node_modules添加到index.html——这就是构建工具的作用。

那么我如何确保变量被导入/解决这个错误?

更多的背景之前,我使用了很棒的-cordova-plugins包装器来安装cordova-purchase-plugin。这是有效的,但awesome-cordova-plugins仅限于cordova-purchase-plugin版本11,我正试图找到一种方法在我的应用程序中使用版本13。

下面是如何在React 18和Ionic React 7、TypeScript 5中使用cordova-purchase-plugin。

部分的例子:

import React from 'react';
import 'cordova-plugin-purchase';
// Some imports omitted.
const PageStoreAppFovea: React.FC = () => {
const history = useHistory();
// These are wrappers for useState() hooks.    
const [isLoading, setIsLoading] = useLoading();
const [showErrorAlert, setShowErrorAlert] = useAlert();
const [showCancelledAlert, setShowCancelledAlert] = useAlert();
const [showSuccessAlert, setShowSuccessAlert] = useAlert();
const [isVerifying, setIsVerifying] = useStateBoolean();
const userObject = useUserObject();
const queryClient = useQueryClient();
const { store } = CdvPurchase;
const monthly = store.get(MyProduct.SubMonthly);
const annual = store.get(MyProduct.SubAnnual);

const buySub = (sub: CdvPurchase.Offer) => {
const productId = sub.id;
setIsLoading(true);
// https://bobbyhadz.com/blog/typescript-check-if-value-exists-in-enum
const allProductsValues = Object.values(MyProduct);
if (allProductsValues.includes(productId)) {
// console.log('placing order for ', productId);
store.applicationUsername = () => userObject.id;
store
.order(sub)
.then(() => {
console.log('order placed', store.get(productId));
})
.catch((error: Error) => {
console.log('error purchased failed', error);
setShowErrorAlert(true);
});
} else {
const errorMessage = `Product is invalid: ${productId}`;
throw new Error(errorMessage);
}
};
// User closed the native purchase dialog
store.when().productUpdated((product) => {
console.log('Purchase cancelled', product);
setIsLoading(false);
setShowCancelledAlert(true);
});
// Upon approval, show a different message.
store.when().approved((product) => {
console.log('Purchase approved', product);
setIsVerifying(true);
});
// Upon the subscription becoming owned.
store.when().finished((product) => {
console.log('Purchase now owned', product);
queryClient
.invalidateQueries({ queryKey: ['myKey'] })
.then(() => setShowSuccessAlert(true))
});
const onClickCancelNotDuringVerify = () => {
setIsLoading(false);
};
const onClickCancelDuringVerify = () => {
setIsVerifying(false);
setIsLoading(false);
};
// console.log('monthly', monthly);
// console.log('annual', annual);
// Todo: Show a message if the free trial is in progress.
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonBackButton defaultHref={'my-route'} />
</IonButtons>
<IonTitle>
<TTitleStore />
</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent>
{!userObject.hasAccessPaidFeatures(myCookie) && (
<BlockSubscriptionExpired />
)}
<p>Mobile store</p>
{isLoading && !isVerifying && (
<>
<p>Please wait...</p>
<ButtonStoreCancel onClick={onClickCancelNotDuringVerify} />
</>
)}
{isLoading && isVerifying && (
<>
<p>Please wait...</p>
<ButtonStoreCancel onClick={onClickCancelDuringVerify} />
</>
)}
{!isLoading && !isVerifying && monthly && annual && (
<ListSubscriptions
monthly={monthly}
annual={annual}
buySub={buySub}
setIsLoading={setIsLoading}
/>
)}
<IonAlert
isOpen={showErrorAlert}
onDidDismiss={() => setShowErrorAlert(false)}
message={tAlertMessagePurchaseFailed}
buttons={['OK']}
/>
<IonAlert
isOpen={showCancelledAlert}
onDidDismiss={() => setShowCancelledAlert(false)}
message={tAlertMessagePurchaseCancelled}
buttons={['OK']}
/>
<IonAlert
isOpen={showSuccessAlert}
onDidDismiss={() => {
history.push(routeTabWelcome);
}}
message={tAlertMessagePurchaseSuccess}
buttons={['OK']}
/>
</IonContent>
</IonPage>
);
};
export default PageStoreAppFovea;

相关内容

  • 没有找到相关文章

最新更新