From e9773fa94cf5f468c9ac57fddcaa6a19de859bce Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Wed, 28 Jan 2026 11:24:29 -0800 Subject: [PATCH 1/4] fix: polyfills with eager install option --- packages/core/globals/index.ts | 8 +++++--- packages/core/globals/{polyfills => }/package.json | 0 2 files changed, 5 insertions(+), 3 deletions(-) rename packages/core/globals/{polyfills => }/package.json (100%) diff --git a/packages/core/globals/index.ts b/packages/core/globals/index.ts index c2171e42e6..7a23dd4dae 100644 --- a/packages/core/globals/index.ts +++ b/packages/core/globals/index.ts @@ -292,8 +292,9 @@ function registerOnGlobalContext(moduleName: string, exportName: string): void { }); } -export function installPolyfills(moduleName: string, exportNames: string[]) { - if (global.__snapshot) { +export function installPolyfills(moduleName: string, exportNames: string[], options?: { eager?: boolean }) { + const shouldInstallEagerly = global.__snapshot || options?.eager; + if (shouldInstallEagerly) { const loadedModule = global.loadModule(moduleName); installPolyfillsFromModule(loadedModule, exportNames as any); } else { @@ -305,7 +306,8 @@ if (!global.NativeScriptHasPolyfilled) { global.NativeScriptHasPolyfilled = true; // console.log('Installing polyfills...'); global.registerModule('timer', () => timer); - installPolyfills('timer', ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval']); + // Timer polyfills are installed eagerly because they are fundamental APIs needed very early + installPolyfills('timer', ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval'], { eager: true }); global.registerModule('animation', () => animationFrame); installPolyfills('animation', ['requestAnimationFrame', 'cancelAnimationFrame']); diff --git a/packages/core/globals/polyfills/package.json b/packages/core/globals/package.json similarity index 100% rename from packages/core/globals/polyfills/package.json rename to packages/core/globals/package.json From 532e0bc9d87fc6cdc21c981b24b8a74110328b79 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Wed, 28 Jan 2026 17:09:38 -0800 Subject: [PATCH 2/4] fix: keep lazy and eager ability --- packages/core/globals/index.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/core/globals/index.ts b/packages/core/globals/index.ts index 7a23dd4dae..c611151bfb 100644 --- a/packages/core/globals/index.ts +++ b/packages/core/globals/index.ts @@ -268,15 +268,15 @@ global.loadModule = function loadModule(name: string): any { } return null; }; -function registerOnGlobalContext(moduleName: string, exportName: string): void { +function registerOnGlobalContext(moduleName: string, exportName: string, moduleRef?: any): void { if (global[exportName]) { // already registered return; } Object.defineProperty(global, exportName, { get: function () { - // We do not need to cache require() call since it is already cached in the runtime. - const m = global.loadModule(moduleName); + // Use pre-captured module reference if available, otherwise use loadModule + const m = moduleRef ?? global.loadModule(moduleName); // Redefine the property to make sure the above code is executed only once. const resolvedValue = m[exportName]; @@ -292,13 +292,13 @@ function registerOnGlobalContext(moduleName: string, exportName: string): void { }); } -export function installPolyfills(moduleName: string, exportNames: string[], options?: { eager?: boolean }) { +export function installPolyfills(moduleName: string, exportNames: string[], options?: { eager?: boolean; moduleRef?: any }) { const shouldInstallEagerly = global.__snapshot || options?.eager; if (shouldInstallEagerly) { - const loadedModule = global.loadModule(moduleName); + const loadedModule = options?.moduleRef ?? global.loadModule(moduleName); installPolyfillsFromModule(loadedModule, exportNames as any); } else { - exportNames.forEach((exportName) => registerOnGlobalContext(moduleName, exportName)); + exportNames.forEach((exportName) => registerOnGlobalContext(moduleName, exportName, options?.moduleRef)); } } @@ -306,8 +306,8 @@ if (!global.NativeScriptHasPolyfilled) { global.NativeScriptHasPolyfilled = true; // console.log('Installing polyfills...'); global.registerModule('timer', () => timer); - // Timer polyfills are installed eagerly because they are fundamental APIs needed very early - installPolyfills('timer', ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval'], { eager: true }); + // Pass moduleRef to ensure timer functions resolve correctly even when accessed very early + installPolyfills('timer', ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval'], { moduleRef: timer }); global.registerModule('animation', () => animationFrame); installPolyfills('animation', ['requestAnimationFrame', 'cancelAnimationFrame']); From 1511dd0c4cc79015c472b05c160f2996cf171e34 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Wed, 28 Jan 2026 18:46:16 -0800 Subject: [PATCH 3/4] chore: keep just eager option --- packages/core/globals/index.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/core/globals/index.ts b/packages/core/globals/index.ts index c611151bfb..7a23dd4dae 100644 --- a/packages/core/globals/index.ts +++ b/packages/core/globals/index.ts @@ -268,15 +268,15 @@ global.loadModule = function loadModule(name: string): any { } return null; }; -function registerOnGlobalContext(moduleName: string, exportName: string, moduleRef?: any): void { +function registerOnGlobalContext(moduleName: string, exportName: string): void { if (global[exportName]) { // already registered return; } Object.defineProperty(global, exportName, { get: function () { - // Use pre-captured module reference if available, otherwise use loadModule - const m = moduleRef ?? global.loadModule(moduleName); + // We do not need to cache require() call since it is already cached in the runtime. + const m = global.loadModule(moduleName); // Redefine the property to make sure the above code is executed only once. const resolvedValue = m[exportName]; @@ -292,13 +292,13 @@ function registerOnGlobalContext(moduleName: string, exportName: string, moduleR }); } -export function installPolyfills(moduleName: string, exportNames: string[], options?: { eager?: boolean; moduleRef?: any }) { +export function installPolyfills(moduleName: string, exportNames: string[], options?: { eager?: boolean }) { const shouldInstallEagerly = global.__snapshot || options?.eager; if (shouldInstallEagerly) { - const loadedModule = options?.moduleRef ?? global.loadModule(moduleName); + const loadedModule = global.loadModule(moduleName); installPolyfillsFromModule(loadedModule, exportNames as any); } else { - exportNames.forEach((exportName) => registerOnGlobalContext(moduleName, exportName, options?.moduleRef)); + exportNames.forEach((exportName) => registerOnGlobalContext(moduleName, exportName)); } } @@ -306,8 +306,8 @@ if (!global.NativeScriptHasPolyfilled) { global.NativeScriptHasPolyfilled = true; // console.log('Installing polyfills...'); global.registerModule('timer', () => timer); - // Pass moduleRef to ensure timer functions resolve correctly even when accessed very early - installPolyfills('timer', ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval'], { moduleRef: timer }); + // Timer polyfills are installed eagerly because they are fundamental APIs needed very early + installPolyfills('timer', ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval'], { eager: true }); global.registerModule('animation', () => animationFrame); installPolyfills('animation', ['requestAnimationFrame', 'cancelAnimationFrame']); From 6ee618217d81a25b09d5623a3b5f534f7537b597 Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Wed, 28 Jan 2026 19:01:10 -0800 Subject: [PATCH 4/4] chore: cleanup --- packages/core/globals/index.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/core/globals/index.ts b/packages/core/globals/index.ts index 7a23dd4dae..b0fd974380 100644 --- a/packages/core/globals/index.ts +++ b/packages/core/globals/index.ts @@ -292,8 +292,8 @@ function registerOnGlobalContext(moduleName: string, exportName: string): void { }); } -export function installPolyfills(moduleName: string, exportNames: string[], options?: { eager?: boolean }) { - const shouldInstallEagerly = global.__snapshot || options?.eager; +export function installPolyfills(moduleName: string, exportNames: string[]) { + const shouldInstallEagerly = global.__snapshot || !__COMMONJS__; if (shouldInstallEagerly) { const loadedModule = global.loadModule(moduleName); installPolyfillsFromModule(loadedModule, exportNames as any); @@ -306,8 +306,7 @@ if (!global.NativeScriptHasPolyfilled) { global.NativeScriptHasPolyfilled = true; // console.log('Installing polyfills...'); global.registerModule('timer', () => timer); - // Timer polyfills are installed eagerly because they are fundamental APIs needed very early - installPolyfills('timer', ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval'], { eager: true }); + installPolyfills('timer', ['setTimeout', 'clearTimeout', 'setInterval', 'clearInterval']); global.registerModule('animation', () => animationFrame); installPolyfills('animation', ['requestAnimationFrame', 'cancelAnimationFrame']);