From b439ab18e829e436542a2b4a965f258d749bfc36 Mon Sep 17 00:00:00 2001 From: Danielku15 Date: Sun, 20 Feb 2022 16:55:58 +0100 Subject: [PATCH] Improve WebPack Support --- src/Environment.ts | 44 +++++++++++++++++++--- src/platform/javascript/BrowserUiFacade.ts | 5 ++- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/Environment.ts b/src/Environment.ts index 4297599eb..0166bdf10 100644 --- a/src/Environment.ts +++ b/src/Environment.ts @@ -188,6 +188,11 @@ export class Environment { */ public static webPlatform: WebPlatform = Environment.detectWebPlatform(); + /** + * @target web + */ + public static isWebPackBundled: boolean = Environment.detectWebPack(); + /** * @target web */ @@ -216,13 +221,25 @@ export class Environment { * @target web */ public static createAlphaTabWorker(scriptFile: string): Worker { - if (Environment.webPlatform === WebPlatform.BrowserModule) { - let script: string = `import * as alphaTab from '${scriptFile}'`; - let blob: Blob = new Blob([script], { type: 'text/javascript' }); + if (Environment.isWebPackBundled) { + // WebPack currently requires this exact syntax: new Worker(new URL(..., import.meta.url))) + // The module `@coderline/alphatab` will be resolved by WebPack to alphaTab consumed as library + // this will not work with CDNs because worker start scripts need to have the same origin like + // the current browser. + + // https://github.com/webpack/webpack/discussions/14066 + + return new Worker( + // @ts-ignore + /* webpackChunkName: "alphatab.worker" */ new URL('@coderline/alphatab', import.meta.url) + ); + } else if (Environment.webPlatform === WebPlatform.BrowserModule) { + const script: string = `import * as alphaTab from '${scriptFile}'`; + const blob: Blob = new Blob([script], { type: 'text/javascript' }); return new Worker(URL.createObjectURL(blob), { type: 'module' }); } else { - let script: string = `importScripts('${scriptFile}')`; - let blob: Blob = new Blob([script]); + const script: string = `importScripts('${scriptFile}')`; + const blob: Blob = new Blob([script]); return new Worker(URL.createObjectURL(blob)); } } @@ -521,6 +538,21 @@ export class Environment { } } + /** + * @target web + */ + private static detectWebPack(): boolean { + try { + // @ts-ignore + if (typeof __webpack_require__ !== 'function') { + return true; + } + } catch (e) { + // ignore any errors + } + return false; + } + /** * @target web */ @@ -541,7 +573,7 @@ export class Environment { try { // @ts-ignore const url: any = import.meta.url; - if (url && typeof url === 'string') { + if (url && typeof url === 'string' && !url.startsWith('file://')) { return WebPlatform.BrowserModule; } } catch (e) { diff --git a/src/platform/javascript/BrowserUiFacade.ts b/src/platform/javascript/BrowserUiFacade.ts index 42b975b3a..92b84fd23 100644 --- a/src/platform/javascript/BrowserUiFacade.ts +++ b/src/platform/javascript/BrowserUiFacade.ts @@ -498,7 +498,10 @@ export class BrowserUiFacade implements IUiFacade { let player: AlphaSynthWebWorkerApi | null = null; let supportsScriptProcessor: boolean = 'ScriptProcessorNode' in window; - let supportsAudioWorklets: boolean = window.isSecureContext && 'AudioWorkletNode' in window; + + // Once https://github.com/webpack/webpack/issues/11543 is decided + // we can support audio worklets together with WebPack + let supportsAudioWorklets: boolean = window.isSecureContext && 'AudioWorkletNode' in window && !Environment.isWebPackBundled; if (supportsAudioWorklets) { Logger.debug('Player', 'Will use webworkers for synthesizing and web audio api with worklets for playback');