From f176bf31f2dcebc272b45cc66feeae78fc931942 Mon Sep 17 00:00:00 2001 From: Tim Paine <3105306+timkpaine@users.noreply.github.com> Date: Fri, 5 Apr 2024 19:32:57 -0400 Subject: [PATCH] Let CDN determine package's entrypoint, fixes #3898 --- packages/html-manager/src/libembed-amd.ts | 41 ++++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/packages/html-manager/src/libembed-amd.ts b/packages/html-manager/src/libembed-amd.ts index 6cf1868c60..75b3e5d114 100644 --- a/packages/html-manager/src/libembed-amd.ts +++ b/packages/html-manager/src/libembed-amd.ts @@ -29,7 +29,10 @@ const requirePromise = function (pkg: string | string[]): Promise { }); }; -function moduleNameToCDNUrl(moduleName: string, moduleVersion: string): string { +function moduleNameToCDNUrl( + moduleName: string, + moduleVersion: string +): { packageRoot: string; pathGuess: string } { let packageName = moduleName; let fileName = 'index'; // default filename // if a '/' is present, like 'foo/bar', packageName is changed to 'foo', and path to 'bar' @@ -45,7 +48,13 @@ function moduleNameToCDNUrl(moduleName: string, moduleVersion: string): string { fileName = moduleName.substr(index + 1); packageName = moduleName.substr(0, index); } - return `${cdn}${packageName}@${moduleVersion}/dist/${fileName}`; + if (moduleVersion.startsWith('~')) { + moduleVersion = moduleVersion.slice(1); + } + return { + packageRoot: `${cdn}${packageName}@${moduleVersion}`, + pathGuess: `/dist/${fileName}`, + }; } /** @@ -72,10 +81,34 @@ export function requireLoader( } function loadFromCDN(): Promise { const conf: { paths: { [key: string]: string } } = { paths: {} }; - conf.paths[moduleName] = moduleNameToCDNUrl(moduleName, moduleVersion); + + // First, try to resolve with the CDN. + // We default to the previous behavior + // of trying for a full path. NOTE: in the + // future, we should let the CDN resolve itself + // based on the package.json contents (the next + // case below) + const { packageRoot, pathGuess } = moduleNameToCDNUrl( + moduleName, + moduleVersion + ); + + conf.paths[moduleName] = `${packageRoot}${pathGuess}`; require.config(conf); - return requirePromise([`${moduleName}`]); + return requirePromise([`${moduleName}`]).catch((err) => { + // Next, if this also errors, we the root + // and let the CDN decide + // NOTE: the `?` is added to avoid require appending a .js + conf.paths[moduleName] = `${packageRoot}?`; + + const failedId = err.requireModules && err.requireModules[0]; + if (failedId) { + require.undef(failedId); + } + require.config(conf); + }); } + if (onlyCDN) { console.log(`Loading from ${cdn} for ${moduleName}@${moduleVersion}`); return loadFromCDN();