From b7089afa0ea1053b4782fc04d83e1bc89dd831dc Mon Sep 17 00:00:00 2001 From: Chaz Gatian Date: Thu, 28 May 2026 05:32:33 -0400 Subject: [PATCH] Conditionally polyfill globals --- shims/buffer/index.ts | 5 +- shims/global/index.ts | 5 +- shims/process/index.ts | 5 +- .../global-references/index.test.ts | 54 +++++++++++++++++++ 4 files changed, 66 insertions(+), 3 deletions(-) diff --git a/shims/buffer/index.ts b/shims/buffer/index.ts index 3bf292b..2e6cdb3 100644 --- a/shims/buffer/index.ts +++ b/shims/buffer/index.ts @@ -1,7 +1,7 @@ import { Blob, BlobOptions, - Buffer, + Buffer as PolyfillBuffer, File, FileOptions, INSPECT_MAX_BYTES, @@ -20,6 +20,9 @@ import { // eslint-disable-next-line unicorn/prefer-node-protocol } from 'buffer' +// Prefer the host's real `globalThis.Buffer` when present +const Buffer = (typeof globalThis !== 'undefined' && (globalThis as { Buffer?: typeof PolyfillBuffer }).Buffer) || PolyfillBuffer + export { Blob, BlobOptions, diff --git a/shims/global/index.ts b/shims/global/index.ts index 538c605..ee0a8ac 100644 --- a/shims/global/index.ts +++ b/shims/global/index.ts @@ -1,5 +1,8 @@ // eslint-disable-next-line @typescript-eslint/no-invalid-this -const global = globalThis || this || self +const polyfillGlobal = globalThis || this || self + +// Prefer the host's real `globalThis.global` when present +const global = (typeof globalThis !== 'undefined' && (globalThis as { global?: typeof polyfillGlobal }).global) || polyfillGlobal export { global } export default global diff --git a/shims/process/index.ts b/shims/process/index.ts index 89616f4..53db766 100644 --- a/shims/process/index.ts +++ b/shims/process/index.ts @@ -2,7 +2,10 @@ // conflict with `node-stdlib-browser` which fails to import `process/browser.js`. // https://github.com/yarnpkg/yarn/issues/6907 // eslint-disable-next-line unicorn/prefer-node-protocol -import process from 'process' +import polyfillProcess from 'process' + +// Prefer the host's real `globalThis.process` when present +const process = (typeof globalThis !== 'undefined' && (globalThis as { process?: typeof polyfillProcess }).process) || polyfillProcess export { process } export default process diff --git a/test/integration/global-references/index.test.ts b/test/integration/global-references/index.test.ts index dc139d4..4ed20f5 100644 --- a/test/integration/global-references/index.test.ts +++ b/test/integration/global-references/index.test.ts @@ -28,6 +28,24 @@ describe('import globals', () => { Buffer.from("test"); `)) }) + + it('resolves to host globalThis.Buffer at runtime', async () => { + const { default: shimBuffer } = await import('vite-plugin-node-polyfills/shims/buffer') + + expect(shimBuffer).toBe((globalThis as { Buffer?: typeof Buffer }).Buffer) + }) + + it('mutations to globalThis.Buffer are observed by the shim', async () => { + const { default: shimBuffer } = await import('vite-plugin-node-polyfills/shims/buffer') as { default: Record } + const key = `__soft_fallback_test_${Date.now()}__` + + try { + ;(globalThis as Record>).Buffer[key] = 'set-on-host' + expect(shimBuffer[key]).toEqual('set-on-host') + } finally { + delete (globalThis as Record>).Buffer[key] + } + }) }) describe('global', () => { @@ -56,6 +74,24 @@ describe('import globals', () => { console.log(global); `)) }) + + it('resolves to host globalThis.global at runtime', async () => { + const { default: shimGlobal } = await import('vite-plugin-node-polyfills/shims/global') + + expect(shimGlobal).toBe((globalThis as { global?: typeof globalThis }).global) + }) + + it('mutations to globalThis.global are observed by the shim', async () => { + const { default: shimGlobal } = await import('vite-plugin-node-polyfills/shims/global') as { default: Record } + const key = `__soft_fallback_test_${Date.now()}__` + + try { + ;(globalThis as Record>).global[key] = 'set-on-host' + expect(shimGlobal[key]).toEqual('set-on-host') + } finally { + delete (globalThis as Record>).global[key] + } + }) }) describe('process', () => { @@ -84,5 +120,23 @@ describe('import globals', () => { console.log(process); `)) }) + + it('resolves to host globalThis.process at runtime', async () => { + const { default: shimProcess } = await import('vite-plugin-node-polyfills/shims/process') + + expect(shimProcess).toBe(globalThis.process) + }) + + it('mutations to globalThis.process are observed by the shim', async () => { + const { default: shimProcess } = await import('vite-plugin-node-polyfills/shims/process') as { default: Record } + const key = `__soft_fallback_test_${Date.now()}__` + + try { + ;(globalThis.process as Record)[key] = 'set-on-host' + expect(shimProcess[key]).toEqual('set-on-host') + } finally { + delete (globalThis.process as Record)[key] + } + }) }) })