Skip to content

Conversation

juj
Copy link
Collaborator

@juj juj commented Sep 29, 2025

Generalize existing Node.js development-time version check into common file that also checks for browser versions.

Copy link
Collaborator

@sbc100 sbc100 left a comment

Choose a reason for hiding this comment

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

Nice!

I was thinking of doing the same thing myself.

I was also thinking that the code for setting ENVIRONMENT_IS_NODE etc could be shared, but that could be followup. I guess we could add that code to this file and call it runtime_environemnt_detect.js or something like that.

* SPDX-License-Identifier: MIT
*/

#include "minimum_runtime_check.js"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe just add this to runtime_common.js which is already included in both runtime modes?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The reason I made a separate file is that this code would be run as the very first thing in the generated .js.

If we put the code somewhere in the middle, we risk already attempting to execute some code that might require a new feature (e.g. ES6 Modules or some language syntax keyword, etc)

Copy link
Collaborator

Choose a reason for hiding this comment

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

Ah yes that makes sense.

var currentSafariVersion = typeof navigator !== 'undefined' && navigator?.userAgent?.includes("Safari/") && navigator.userAgent.match(/Version\/(\d+\.?\d*\.?\d*)/) ? humanReadableVersionToPacked(navigator.userAgent.match(/Version\/(\d+\.?\d*\.?\d*)/)[1]) : TARGET_NOT_SUPPORTED;
if (currentSafariVersion < {{{ MIN_SAFARI_VERSION }}}) throw new Error(`This emscripten-generated code requires Safari v${ packedVersionToHumanReadable({{{ MIN_SAFARI_VERSION }}}) } (detected v${currentSafariVersion})`);

var currentFirefoxVersion = typeof navigator !== 'undefined' && navigator?.userAgent?.match(/Firefox\/(\d+(?:\.\d+)?)/) ? parseFloat(navigator.userAgent.match(/Firefox\/(\d+(?:\.\d+)?)/)[1]) : TARGET_NOT_SUPPORTED;
Copy link
Collaborator

Choose a reason for hiding this comment

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

These days you can do globalThis.navigator?.userAgent?.match avoiding the need for the typeof check. It makes it a little smaller and easier to read.

See #25375 and #25381.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That would require globalThis, which might not exist in an old browser. This is an ASSERTIONS check anyways, so code size is not that critical.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Oh I see, we know the globalThis exists on supported browser, but here we are trying to explicitly detect unsupported ones. That makes sense.

I guess you should do check for typeof globalThis first before the other checks? lgtm either way though

if (currentFirefoxVersion < {{{ MIN_FIREFOX_VERSION }}}) throw new Error(`This emscripten-generated code requires Firefox v{{{ MIN_FIREFOX_VERSION }}} (detected v${currentFirefoxVersion})`);

var currentChromeVersion = typeof navigator !== 'undefined' && navigator?.userAgent?.match(/Chrome\/(\d+(?:\.\d+)?)/) ? parseFloat(navigator.userAgent.match(/Chrome\/(\d+(?:\.\d+)?)/)[1]) : TARGET_NOT_SUPPORTED;
if (currentChromeVersion < {{{ MIN_CHROME_VERSION }}}) throw new Error(`This emscripten-generated code requires Chrome v{{{ MIN_CHROME_VERSION }}} (detected v${currentChromeVersion})`);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe wrap this whole file in an IFFE to avoid creating all these global vars?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Now that this is in an IFFY (so these are just local vars) could we shorten all the currentChromeVersion to just chromeVersion for readability?

}

var currentFirefoxVersion = typeof navigator !== 'undefined' && navigator?.userAgent?.match(/Firefox\/(\d+(?:\.\d+)?)/) ? parseFloat(navigator.userAgent.match(/Firefox\/(\d+(?:\.\d+)?)/)[1]) : TARGET_NOT_SUPPORTED;
if (currentFirefoxVersion < TARGET_NOT_SUPPORTED && 79 == TARGET_NOT_SUPPORTED) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

79 == TARGET_NOT_SUPPORTED looks like typo.. is it not?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That was just runtime test on what could have been a compile time check. Optimized it to take place at compile time.

juj added 3 commits September 29, 2025 22:31
…vironments

# Conflicts:
#	test/codesize/test_codesize_hello_O0.json
#	test/codesize/test_codesize_minimal_O0.json
#	test/codesize/test_unoptimized_code_size.json
@juj juj merged commit 2c18c95 into emscripten-core:main Sep 29, 2025
33 checks passed
juj added a commit to juj/emscripten that referenced this pull request Oct 7, 2025
…nd require users to pass 'web' or 'node' to disambiguate. Fixes emscripten-core#25414 (review).
juj added a commit that referenced this pull request Oct 8, 2025
…25514)

Remove the 'ENVIRONMENT=worker implies ENVIRONMENT=web' assumption.
Fixes
#25414 (review).
Add test to verify the expectation mentioned in that comment.
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

Successfully merging this pull request may close these issues.

3 participants