Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web Audio Workers do not have access to global scope self #4988

Closed
FallingSnow opened this issue Sep 1, 2023 · 1 comment
Closed

Web Audio Workers do not have access to global scope self #4988

FallingSnow opened this issue Sep 1, 2023 · 1 comment

Comments

@FallingSnow
Copy link

Bug report

I'm running into an issue while using web audio workers. It seems there isn't a target that uses globalThis instead of self. The code causing the issue is below.

self.addEventListener("beforeunload", () => {
status.isUnloading = true;
});

AudioWorkletGlobalScope defines the only scope available to a web audio worker.

Actual Behavior

ReferenceError: self is not defined

I have tried changing the globalObject in my webpack config but it seems webpack-dev-server doesn't use this option.

output: {
  globalObject: "globalThis"
}

I also tried setting the target to webworker but the error persists.

Expected Behavior

Either code generated should use the globalObject set by webpack or default to globalThis.
Or the self code portions should not be included in web worker output.

How Do We Reproduce?

Create a audio worker using code compiled by webpack-dev-server and register it using the same name as below; "realtime-audio". The audio worker file should be complied to a separate bundle. See https://developer.mozilla.org/en-US/docs/Web/API/AudioWorkletNode for another complete example.

audio.ts

export class RealtimeAudio extends AudioWorkletProcessor {

  constructor() {
    super();
    console.debug("Created realtime audio player");
  }

  process(
    inputs: Float32Array[][],
    outputs: Float32Array[][],
    parameters: Record<string, Float32Array>
  ): boolean {
    return true;
  }
}

registerProcessor("realtime-audio", RealtimeAudio);

main.ts

let audioCtx = new AudioContext({
  latencyHint: "interactive",
  sampleRate: 48_000,
});
audioCtx.audioWorklet.addModule("audio.bundle.js");
let worker = new AudioWorkletNode(audioCtx, "realtime-audio", {});

This should trigger the error.

Please paste the results of npx webpack-cli info here, and mention other relevant information

  System:
    OS: Linux 6.4 Arch Linux
    CPU: (8) x64 13th Gen Intel(R) Core(TM) i5-13600K
    Memory: 498.34 MB / 2.86 GB
  Binaries:
    Node: 20.5.1 - ~/.nvm/versions/node/v20.5.1/bin/node
    Yarn: 1.22.19 - ~/.nvm/versions/node/v20.5.1/bin/yarn
    npm: 9.8.0 - ~/.nvm/versions/node/v20.5.1/bin/npm
  Packages:
    compression-webpack-plugin: ^10.0.0 => 10.0.0
    css-loader: ^6.8.1 => 6.8.1
    html-webpack-plugin: ^5.5.1 => 5.5.1
    strict-csp-html-webpack-plugin: 1.0.0-beta.2 => 1.0.0-beta.2
    style-loader: ^3.3.3 => 3.3.3
    swc-loader: ^0.2.3 => 0.2.3
    webpack: ^5.85.0 => 5.85.0
    webpack-bundle-analyzer: ^4.9.0 => 4.9.0
    webpack-cli: ^5.1.1 => 5.1.1
    webpack-dev-server: ^4.15.1 => 4.15.1
    webpack-subresource-integrity: 5.2.0-rc.1 => 5.2.0-rc.1
@alexander-akait
Copy link
Member

You don't need to use client (and maybe hot, but it depends on your goals), please use:

module.exports = [
  {
    entry: "./src/index.js",
    mode: "development",
    output: {
      path: path.resolve(__dirname, "./dist"),
      filename: "main.js",
    },
  },
  {
    entry: "./src/audio.js",
    mode: "development",
    target: "webworker",
    output: {
      publicPath: "",
      path: path.resolve(__dirname, "./dist"),
      filename: "audio.bundle.js",
    },
    devServer: {
      client: false,
      hot: false,
    }
  }
];

i.e. you disable client and hot on your audio worklet.

But there is a small problem, you can't use dev server options for the first compilation, but we are working on it webpack/webpack-cli#4045 and release will be soon, after cut a release you can do such things:

module.exports = [
  {
    entry: "./src/index.js",
    mode: "development",
    output: {
      path: path.resolve(__dirname, "./dist"),
      filename: "main.js",
    },
    devServer: {
      // Your options for dev server
    }
  },
  {
    entry: "./src/audio.js",
    mode: "development",
    target: "webworker",
    output: {
      publicPath: "",
      path: path.resolve(__dirname, "./dist"),
      filename: "audio.bundle.js",
    },
    devServer: false
  }
];

Sorry for delay and feel free to feedback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants