Skip to content

[browser][coreclr] Fix corerun to run in browser again#125322

Merged
radekdoulik merged 3 commits intodotnet:mainfrom
radekdoulik:clr-wasm-fix-corerun-in-browser
Mar 10, 2026
Merged

[browser][coreclr] Fix corerun to run in browser again#125322
radekdoulik merged 3 commits intodotnet:mainfrom
radekdoulik:clr-wasm-fix-corerun-in-browser

Conversation

@radekdoulik
Copy link
Member

@radekdoulik radekdoulik commented Mar 9, 2026

The corerun build uses -sEXPORT_ES6=1 -sMODULARIZE=1, producing corerun.js as an ES6 module. Several issues prevented it from running in the browser:

  • corerun.html loaded corerun.js with a plain <script> tag, causing
    "Cannot use import.meta outside a module". Fixed by using

    <script type="module"> with an ES6 import of the selfRun export.
  • libCorerun.extpost.js had 'var fetch = fetch || undefined' which
    in ES6 module scope shadows the global fetch API due to hoisting,
    breaking WASM loading. Removed the declaration. Also guarded
    process.exit() for Node.js only and made selfRun() auto-run only
    in Node.js (in browser it is called from corerun.html with config).

  • The preRun callback used bare FS/ENV globals which don't exist in
    modularized output. Fixed by accessing them via the module parameter.
    Additionally, Emscripten's --preload-file data is loaded by an async
    preRun callback whose fetch hasn't completed when our preRun runs.
    Fixed by using addRunDependency/monitorRunDependencies to defer
    main() until the preloaded files are available in the virtual FS.

  • libCorerun.js unconditionally depended on $NODEFS/$NODERAWFS which
    are unavailable in browser builds. Use LibraryManager.library checks
    to conditionally include them only when present.

Also added ENV to EXPORTED_RUNTIME_METHODS so the preRun callback can
set APP_ASSEMBLIES via module.ENV.

The corerun build uses -sEXPORT_ES6=1 -sMODULARIZE=1, producing
corerun.js as an ES6 module. Three issues prevented it from running
in the browser:

1. corerun.html loaded corerun.js with a plain <script> tag, causing
   "Cannot use import.meta outside a module". Fixed by using
   <script type="module"> with an ES6 import of the selfRun export.

2. libCorerun.extpost.js had 'var fetch = fetch || undefined' which
   in ES6 module scope shadows the global fetch API due to hoisting,
   breaking WASM loading. Removed the declaration. Also guarded
   process.exit() for Node.js only and made selfRun() auto-run only
   in Node.js (in browser it is called from corerun.html with config).

3. The preRun callback used bare FS/ENV globals which don't exist in
   modularized output. Fixed by accessing them via the module parameter.
   Additionally, Emscripten's --preload-file data is loaded by an async
   preRun callback whose fetch hasn't completed when our preRun runs.
   Fixed by using addRunDependency/monitorRunDependencies to defer
   main() until the preloaded files are available in the virtual FS.

Also added ENV to EXPORTED_RUNTIME_METHODS so preRun can set
APP_ASSEMBLIES via module.ENV.
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @agocke, @dotnet/runtime-infrastructure
See info in area-owners.md if you want to be subscribed.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes the CoreCLR corerun WASM host so the ES6-modularized corerun.js can run in a browser again (in addition to Node), aligning corerun.html and the JS glue code with Emscripten’s -sEXPORT_ES6=1 -sMODULARIZE=1 output.

Changes:

  • Update corerun.html to load corerun.js as an ES module and call the exported selfRun() with a module config.
  • Adjust libCorerun.extpost.js to avoid shadowing global fetch, and to only auto-run / call process.exit() in Node.
  • Add a browser-specific Emscripten JS library (libCorerun.browser.js) and export ENV so browser preRun can set APP_ASSEMBLIES.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/coreclr/hosts/corerun/wasm/libCorerun.extpost.js Makes selfRun() configurable and Node-only auto-run; avoids fetch shadowing in ES module scope.
src/coreclr/hosts/corerun/wasm/libCorerun.browser.js Provides a browser-only Emscripten library variant without Node FS dependencies.
src/coreclr/hosts/corerun/wasm/corerun.html Loads corerun.js as an ES module and invokes selfRun() with browser config + preload dependency gating.
src/coreclr/hosts/corerun/CMakeLists.txt Switches JS library based on CORERUN_IN_BROWSER and exports ENV for runtime config.

@radekdoulik radekdoulik enabled auto-merge (squash) March 10, 2026 10:31
@radekdoulik radekdoulik merged commit 2e14703 into dotnet:main Mar 10, 2026
117 of 119 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants