Skip to content

Babel/core-js URL polyfill breaks Webpack's new URL() for Web Workers #240

@gregaou

Description

@gregaou

When @babel/preset-env targets an older browser environment (e.g., chrome >= 52) that lacks native support for the new URL(..., import.meta.url) syntax, it injects a polyfill for the URL constructor from core-js. This polyfilled URL constructor interferes with Webpack's static analysis for Web Workers, which specifically looks for the new URL(...) pattern.

As a result, Webpack fails to create a separate chunk for the worker. Instead, the core-js polyfill is invoked with an incorrect, non-functional path, causing the worker instantiation to fail at runtime.

Environment

  • @babel/core: ^7.24.7
  • @babel/preset-env: ^7.24.7
  • webpack: ^5.91.0
  • babel-loader: ^9.1.3
  • core-js-pure: ^3.43.0
  • babel-plugin-polyfill-corejs3: ^0.12.0

Steps to Reproduce

A full reproduction repository is available here: https://github.com/gregaou/example-babel-polyfill-workers

  1. Clone the repository.
  2. Ensure the .browserslistrc file targets an older browser:
    chrome >= 52
    
  3. Install dependencies (npm install or yarn).
  4. Run the build (npm run build or yarn build).
  5. Inspect the generated output in dist/.

Expected Behavior

When targeting a modern browser like chrome >= 67 (where new URL(..., import.meta.url) is natively supported), Babel does not polyfill URL. Webpack correctly identifies the syntax and generates a functional worker loader:

// Correct output for modern targets
const newFibWorker = new Worker(new URL(/* worker import */ __webpack_require__.p + __webpack_require__.u("src_worker_ts-_..."), __webpack_require__.b));

This code works as expected.

Actual Behavior

When targeting chrome >= 52, @babel/preset-env injects the core-js polyfill for URL. The resulting code in the bundle looks like this:

// Incorrect output for older targets
const newFibWorker = new Worker(new (core_js_pure_stable_url_index_js__WEBPACK_IMPORTED_MODULE_2___default())('./worker.ts', "file:///.../src/index.tsx"));

This fails at runtime because:

  1. The new URL(...) syntax that Webpack's parser looks for has been replaced.
  2. The core-js polyfill is invoked with a file-system path (import.meta.url is transpiled to a file path), which is not a valid base for creating a worker URL in the browser.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions