Skip to content

Commit

Permalink
Test forcing esm with umd fallback
Browse files Browse the repository at this point in the history
  • Loading branch information
imx-mikhala committed Feb 14, 2024
1 parent 1aa4cdc commit 9356110
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 27 deletions.
68 changes: 45 additions & 23 deletions packages/checkout/sdk/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand Down Expand Up @@ -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<ImmutableCheckoutWidgets.WidgetsFactory>((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<ImmutableCheckoutWidgets.WidgetsFactory>((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.
Expand All @@ -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();
}
Expand All @@ -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.
Expand Down
3 changes: 0 additions & 3 deletions packages/checkout/sdk/src/types/widgets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
2 changes: 1 addition & 1 deletion packages/checkout/sdk/src/widgets/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 9356110

Please sign in to comment.