From d01377da3c1eee2d7e5d5031362b2d27b27f9cf6 Mon Sep 17 00:00:00 2001 From: Steve Repsher Date: Mon, 1 Jul 2024 10:31:22 -0400 Subject: [PATCH] Fix Webpack bundling of recorder worklet (#21239) * Fix Webpack bundling of recorder worklet --- build-scripts/webpack.cjs | 17 ++++++++++++----- src/util/audio-recorder.ts | 17 +++++++++-------- ...{recorder.worklet.js => recorder-worklet.js} | 2 +- 3 files changed, 22 insertions(+), 14 deletions(-) rename src/util/{recorder.worklet.js => recorder-worklet.js} (89%) diff --git a/build-scripts/webpack.cjs b/build-scripts/webpack.cjs index 0679e3e2baec..5ba0f35d2383 100644 --- a/build-scripts/webpack.cjs +++ b/build-scripts/webpack.cjs @@ -74,6 +74,9 @@ const createWebpackConfig = ({ resolve: { fullySpecified: false, }, + parser: { + worker: ["*context.audioWorklet.addModule()", "..."], + }, }, { test: /\.css$/, @@ -92,11 +95,15 @@ const createWebpackConfig = ({ moduleIds: isProdBuild && !isStatsBuild ? "deterministic" : "named", chunkIds: isProdBuild && !isStatsBuild ? "deterministic" : "named", splitChunks: { - // Disable splitting for web workers with ESM output - // Imports of external chunks are broken - chunks: latestBuild - ? (chunk) => !chunk.canBeInitial() && !/^.+-worker$/.test(chunk.name) - : undefined, + // Disable splitting for web workers and worklets because imports of + // external chunks are broken for: + // - ESM output: https://github.com/webpack/webpack/issues/17014 + // - Worklets use `importScripts`: https://github.com/webpack/webpack/issues/11543 + chunks: (chunk) => + !chunk.canBeInitial() && + !new RegExp(`^.+-work${latestBuild ? "(?:let|er)" : "let"}$`).test( + chunk.name + ), }, }, plugins: [ diff --git a/src/util/audio-recorder.ts b/src/util/audio-recorder.ts index b26f0f49229c..30bf78793709 100644 --- a/src/util/audio-recorder.ts +++ b/src/util/audio-recorder.ts @@ -70,17 +70,18 @@ export class AudioRecorder { } private async _createContext() { - // @ts-ignore-next-line - this._context = new (window.AudioContext || window.webkitAudioContext)(); + // @ts-expect-error webkitAudioContext is not recognized + const context = new (AudioContext || webkitAudioContext)(); this._stream = await navigator.mediaDevices.getUserMedia({ audio: true }); - - await this._context.audioWorklet.addModule( - new URL("./recorder.worklet.js", import.meta.url) + // Syntax here must match an item of `parser.worker` in Webpack config in + // order for module to be parsed and a chunk to be properly created. + await context.audioWorklet.addModule( + /* webpackChunkName: "recorder-worklet" */ + new URL("./recorder-worklet.js", import.meta.url) ); - + this._context = context; this._source = this._context.createMediaStreamSource(this._stream); - this._recorder = new AudioWorkletNode(this._context, "recorder.worklet"); - + this._recorder = new AudioWorkletNode(this._context, "recorder-worklet"); this._recorder.port.onmessage = (e) => { if (!this._active) { return; diff --git a/src/util/recorder.worklet.js b/src/util/recorder-worklet.js similarity index 89% rename from src/util/recorder.worklet.js rename to src/util/recorder-worklet.js index b8fef662e727..0d54b3a607c9 100644 --- a/src/util/recorder.worklet.js +++ b/src/util/recorder-worklet.js @@ -18,4 +18,4 @@ class RecorderProcessor extends AudioWorkletProcessor { } } -registerProcessor("recorder.worklet", RecorderProcessor); +registerProcessor("recorder-worklet", RecorderProcessor);