Skip to content

[Bug]: playground - Published package references monaco workers via hard-coded /assets/... URLs, breaking every consumer #11991

Description

@dalbrx-nitrobox

Describe the bug

Since @typespec/playground@0.17.1, the published package loads its monaco workers from
hard-coded absolute URLs pointing into the package's own build output layout:

node_modules/@typespec/playground/dist/editor.worker-Biegl0p7.js

function WorkerWrapper(options) {
	return new Worker("/assets/editor.worker-CBxI71al.js", { name: options?.name });
}

node_modules/@typespec/playground/dist/json.worker-j8mDmDqS.js

	return new Worker("/assets/json.worker-BMpfVdM-.js", { name: options?.name });

Both files exist in the package (dist/assets/editor.worker-CBxI71al.js,
dist/assets/json.worker-BMpfVdM-.js), but the URL is a site-root absolute path, so it only
resolves if the consuming app happens to serve the package's dist/assets folder at /assets.
In any downstream app (and with any non-/ base path), GET /assets/editor.worker-CBxI71al.js
falls through to the SPA fallback and returns index.html.

In 0.17.0 the workers were still plain ?worker imports that the consumer's bundler resolved:

const { default: editorWorker } = await import("monaco-editor/esm/vs/editor/editor.worker?worker");

Actual behavior

The monaco workers never start and the console shows:

Uncaught SyntaxError: Unexpected token '<'
    at http://localhost:5173/assets/editor.worker-CBxI71al.js
Uncaught [object ErrorEvent]
    at .../monaco-editor/esm/vs/base/common/errors.js

Expected behavior

The worker assets are resolved relative to the module that requests them (e.g. via
new URL(..., import.meta.url) or by leaving the monaco-editor/...?worker imports to the
consuming bundler), so they keep working regardless of where the consumer serves the app from
and under any base.

Affected versions

version worker loading
0.17.0, 0.17.1-dev.0, 0.17.1-dev.1 ?worker import, works
0.17.1-dev.2, 0.17.1, 0.17.2-dev.1, 0.18.0-dev.2 hard-coded /assets/..., broken

So the regression was introduced between 0.17.1-dev.1 and 0.17.1-dev.2, most likely by the
change that made the playground's own build pre-bundle the monaco workers instead of re-exporting
the ?worker imports.

Workaround for consumers

Serve the package's asset folder from the site root, e.g. as a small Vite plugin:

const assetsDir = join(dirname(require.resolve("@typespec/playground")), "assets");
// dev: middleware serving /assets/<file> from assetsDir
// build: this.emitFile({ type: "asset", fileName: `assets/${file}`, source: readFileSync(...) })

Reproduction

  1. Create a Vite app that depends on @typespec/playground@0.17.1 (same setup as
    packages/playground-website) and calls registerMonacoDefaultWorkersForVite().
  2. Run the dev server or serve a production build.
  3. Open the playground and watch the browser console.

Checklist

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions