From 9356110da64f424169bd0030433ac6b8ec37fe00 Mon Sep 17 00:00:00 2001 From: Mikhala Date: Wed, 14 Feb 2024 10:11:00 +0800 Subject: [PATCH] Test forcing esm with umd fallback --- packages/checkout/sdk/src/sdk.ts | 68 ++++++++++++++-------- packages/checkout/sdk/src/types/widgets.ts | 3 - packages/checkout/sdk/src/widgets/load.ts | 2 +- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/packages/checkout/sdk/src/sdk.ts b/packages/checkout/sdk/src/sdk.ts index 462a05844f..16b827c087 100644 --- a/packages/checkout/sdk/src/sdk.ts +++ b/packages/checkout/sdk/src/sdk.ts @@ -65,10 +65,12 @@ import { FiatRampService, FiatRampWidgetParams } from './fiatRamp'; import { getItemRequirementsFromRequirements } from './smartCheckout/itemRequirements'; import { CheckoutError, CheckoutErrorType } from './errors'; import { AvailabilityService, availabilityService } from './availability'; -import { getCdnUrl, loadUnresolvedBundle } from './widgets/load'; +import { getWidgetsEsmUrl, loadUnresolvedBundle } from './widgets/load'; import { WidgetsInit } from './types/widgets'; import { HttpClient } from './api/http'; import { isMatchingAddress } from './utils/utils'; +import { WidgetConfiguration } from './widgets/definitions/configurations'; +import { SemanticVersion } from './widgets/definitions/types'; const SANDBOX_CONFIGURATION = { baseConfig: { @@ -119,32 +121,28 @@ export class Checkout { // Preload the configurations await checkout.config.remote.getConfig(); - // Resolves the factory for the esm build of the widgets - if (init.useEsModules) { - const cdnUrl = getCdnUrl(init.version); - // WebpackIgnore comment required to prevent webpack modifying the import statement and - // breaking the dynamic import in certain applications integrating checkout - const checkoutWidgetsModule = await import(/* webpackIgnore: true */ cdnUrl); - - const factory = new Promise((resolve, reject) => { - if (checkoutWidgetsModule && checkoutWidgetsModule.WidgetsFactory) { - resolve(new checkoutWidgetsModule.WidgetsFactory(checkout, init.config)); - } else { - reject(new CheckoutError( - 'Unable to resolve the WidgetsFactory from the checkout widgets module', - CheckoutErrorType.WIDGETS_SCRIPT_LOAD_ERROR, - )); - } - }); - + try { + const factory = await this.loadEsModules(init.config, init.version); return factory; + } catch (err: any) { + throw new CheckoutError( + 'Failed to load widgets script', + CheckoutErrorType.WIDGETS_SCRIPT_LOAD_ERROR, + { error: err }, + ); } + } + + private async loadUmdBundle( + config: WidgetConfiguration, + version?: SemanticVersion, + ) { + const checkout = this; - // Resolves the factory for the umd build of the widgets const factory = new Promise((resolve, reject) => { function checkForWidgetsBundleLoaded() { if (typeof ImmutableCheckoutWidgets !== 'undefined') { - resolve(new ImmutableCheckoutWidgets.WidgetsFactory(checkout, init.config)); + resolve(new ImmutableCheckoutWidgets.WidgetsFactory(checkout, config)); } else { // If ImmutableCheckoutWidgets is not defined, wait for set amount of time. // When time has elapsed, check again if ImmutableCheckoutWidgets is defined. @@ -154,9 +152,9 @@ export class Checkout { } try { - const script = loadUnresolvedBundle(init.version); + const script = loadUnresolvedBundle(version); if (script.loaded && typeof ImmutableCheckoutWidgets !== 'undefined') { - resolve(new ImmutableCheckoutWidgets.WidgetsFactory(checkout, init.config)); + resolve(new ImmutableCheckoutWidgets.WidgetsFactory(checkout, config)); } else { checkForWidgetsBundleLoaded(); } @@ -174,6 +172,30 @@ export class Checkout { return factory; } + private async loadEsModules( + config: WidgetConfiguration, + version?: SemanticVersion, + ) { + const checkout = this; + try { + const cdnUrl = getWidgetsEsmUrl(version); + + // WebpackIgnore comment required to prevent webpack modifying the import statement and + // breaking the dynamic import in certain applications integrating checkout + const checkoutWidgetsModule = await import(/* webpackIgnore: true */ cdnUrl); + + if (checkoutWidgetsModule && checkoutWidgetsModule.WidgetsFactory) { + return new checkoutWidgetsModule.WidgetsFactory(checkout, config); + } + } catch (err: any) { + // eslint-disable-next-line no-console + console.warn(`Failed to resolve checkout widgets module, falling back to UMD bundle. Error: ${err.message}`); + } + + // Fallback to UMD bundle if esm bundle fails to load + return await checkout.loadUmdBundle(config, version); + } + /** * Creates a provider using the given parameters. * @param {CreateProviderParams} params - The parameters for creating the provider. diff --git a/packages/checkout/sdk/src/types/widgets.ts b/packages/checkout/sdk/src/types/widgets.ts index 02e38ef327..76f9ecf70d 100644 --- a/packages/checkout/sdk/src/types/widgets.ts +++ b/packages/checkout/sdk/src/types/widgets.ts @@ -5,11 +5,8 @@ import { SemanticVersion } from '../widgets/definitions/types'; * Represents the configuration options for instantiating the Checkout Widgets factory. * @property {WidgetConfiguration} config - global configuration options for the widgets. * @property {SemanticVersion | undefined} version - version of the Checkout widgets bundle(default latest version will be used). - * @property {boolean | undefined} useEsModules - Set to true to use the esm build of the widgets. */ export type WidgetsInit = { config: WidgetConfiguration; version?: SemanticVersion; - /** Loads separate parts of the widget script as required for performance improvements. */ - useEsModules?: boolean; }; diff --git a/packages/checkout/sdk/src/widgets/load.ts b/packages/checkout/sdk/src/widgets/load.ts index 82622d68a8..ba76d0afe5 100644 --- a/packages/checkout/sdk/src/widgets/load.ts +++ b/packages/checkout/sdk/src/widgets/load.ts @@ -37,7 +37,7 @@ export function loadUnresolvedBundle( } // Gets the CDN url for the split checkout widgets bundle -export function getCdnUrl( +export function getWidgetsEsmUrl( version?: SemanticVersion, ): string { const validVersion = validateAndBuildVersion(version);