Turbopack: Use a real file entrypoint for Workers (and SharedWorkers) (#88602)
# What
Closes https://github.com/vercel/next.js/issues/84782
Closes https://github.com/vercel/next.js/issues/74842
Closes https://github.com/vercel/next.js/issues/82520
Closes PACK-3723
Replace blob URLs for web workers with real entrypoint files, fixing relative URL resolution inside workers. Implements support for `SharedWorkers` since it's now a simple variation of the `Worker` case.
Note that all generated files (and shared-worker querystrings) are appropriately content-hashed and do not rely on deployment IDs and will work w/immutable resources.
# Why
Workers created via `new Worker(new URL('./worker.js', import.meta.url))` previously got blob URLs. This breaks relative URL resolution inside workers - WASM imports like `new URL('./file.wasm', import.meta.url)` fail because `import.meta.url` returns `blob:http://...` instead of a real path.
# How
We emit a real worker entrypoint file instead of blob URLs. The entrypoint reads bootstrap config from URL hash params (`#params=....`), then loads the worker's chunks via `importScripts`.
The `ChunkingContext` trait gets a new `worker_entrypoint()` method returning a singleton bootstrap asset. Node.js `bail!`s for now but could implement its own in the future. The browser implementation (`EcmascriptBrowserWorkerEntrypoint`) compiles and minifies `worker-entrypoint.ts`, which parses `#params={globals,chunks}` from the URL at runtime.
`WorkerLoaderChunkItem` now emits `__turbopack_worker_url__(entrypoint, chunks, shared)` instead of the old blob URL shim. SharedWorker passes `shared=true` which adds a querystring - the browser handles worker identity via URL, so same URL means same instance.
Generated code changes (pseudocode):
```javascript
__turbopack_export_value__(__turbopack_worker_blob_url__(["chunk1.js", "chunk2.js"]));
```
After:
```javascript
__turbopack_export_value__(__turbopack_worker_url__("worker-entrypoint.js", ["chunk1.js", "chunk2.js"], false));
```
# Notes
Webpack doesn't currently correctly support `SharedWorkers`. The e2e test behaves properly in turbopack after this change, but webpack spins up two separate workers where it should only be spinning up one.
I generated snapshot tests for workers in the first and last commits to help understand the generated code better.
# Testing
- Snapshot tests for Worker, SharedWorker, and minified output
- E2E tests for WASM loading in workers (`test/e2e/app-dir/worker/`)