From 94d19038e15a481e71c02947a857a882265ef07d Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Mon, 16 Aug 2021 10:55:24 +0200 Subject: [PATCH] check for runtime support --- .../__tests__/runtime_require_module.test.js | 18 ++++---- packages/jest-runtime/src/index.ts | 45 +++++++++++++++---- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/packages/jest-runtime/src/__tests__/runtime_require_module.test.js b/packages/jest-runtime/src/__tests__/runtime_require_module.test.js index 3cabb041808f..8dd185c562ac 100644 --- a/packages/jest-runtime/src/__tests__/runtime_require_module.test.js +++ b/packages/jest-runtime/src/__tests__/runtime_require_module.test.js @@ -188,15 +188,17 @@ describe('Runtime requireModule', () => { }).not.toThrow(); }); - it('finds node core built-in modules with node:prefix', async () => { - const runtime = await createRuntime(__filename); + onNodeVersions('^16.0.0', () => { + it('finds node core built-in modules with node:prefix', async () => { + const runtime = await createRuntime(__filename); - expect(runtime.requireModule(runtime.__mockRootPath, 'fs')).toBe( - runtime.requireModule(runtime.__mockRootPath, 'node:fs'), - ); - expect(runtime.requireModule(runtime.__mockRootPath, 'module')).toBe( - runtime.requireModule(runtime.__mockRootPath, 'node:module'), - ); + expect(runtime.requireModule(runtime.__mockRootPath, 'fs')).toBe( + runtime.requireModule(runtime.__mockRootPath, 'node:fs'), + ); + expect(runtime.requireModule(runtime.__mockRootPath, 'module')).toBe( + runtime.requireModule(runtime.__mockRootPath, 'node:module'), + ); + }); }); it('finds and loads JSON files without file extension', async () => { diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index e0685603e798..a28a35f6f73d 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -149,6 +149,28 @@ const supportsTopLevelAwait = } })(); +const supportsNodeColonModulePrefixInRequire = (() => { + try { + require('node:fs'); + + return true; + } catch { + return false; + } +})(); + +const supportsNodeColonModulePrefixInImport = (async () => { + try { + // @ts-expect-error + // eslint-disable-next-line import/no-unresolved + await import('node:fs'); + + return true; + } catch { + return false; + } +})(); + export default class Runtime { private readonly _cacheFS: Map; private readonly _config: Config.ProjectConfig; @@ -411,7 +433,7 @@ export default class Runtime { ); if (this._resolver.isCoreModule(modulePath)) { - const core = this._importCoreModule(modulePath, context); + const core = await this._importCoreModule(modulePath, context); this._esmoduleRegistry.set(cacheKey, core); transformResolve(); @@ -645,7 +667,10 @@ export default class Runtime { } if (moduleName && this._resolver.isCoreModule(moduleName)) { - return this._requireCoreModule(moduleName); + return this._requireCoreModule( + moduleName, + supportsNodeColonModulePrefixInRequire, + ); } if (!modulePath) { @@ -1331,10 +1356,11 @@ export default class Runtime { } } - private _requireCoreModule(moduleName: string) { - const moduleWithoutNodePrefix = moduleName.startsWith('node:') - ? moduleName.slice('node:'.length) - : moduleName; + private _requireCoreModule(moduleName: string, supportPrefix: boolean) { + const moduleWithoutNodePrefix = + supportPrefix && moduleName.startsWith('node:') + ? moduleName.slice('node:'.length) + : moduleName; if (moduleWithoutNodePrefix === 'process') { return this._environment.global.process; @@ -1347,8 +1373,11 @@ export default class Runtime { return require(moduleWithoutNodePrefix); } - private _importCoreModule(moduleName: string, context: VMContext) { - const required = this._requireCoreModule(moduleName); + private async _importCoreModule(moduleName: string, context: VMContext) { + const required = this._requireCoreModule( + moduleName, + await supportsNodeColonModulePrefixInImport, + ); const module = new SyntheticModule( ['default', ...Object.keys(required)],