From 67f7e6355127b979efc5c3744023e222c00106b9 Mon Sep 17 00:00:00 2001 From: Tommaso Bossi Date: Wed, 16 Feb 2022 08:36:43 +0100 Subject: [PATCH] refactor: use `SyntheticModule` for json data URI import --- e2e/native-esm/__tests__/native-esm.test.js | 8 +-- e2e/native-esm/staticDataImport.js | 2 +- packages/jest-runtime/src/index.ts | 59 ++++++++++++--------- 3 files changed, 39 insertions(+), 30 deletions(-) diff --git a/e2e/native-esm/__tests__/native-esm.test.js b/e2e/native-esm/__tests__/native-esm.test.js index 9219a24749ff..73a652bdac5e 100644 --- a/e2e/native-esm/__tests__/native-esm.test.js +++ b/e2e/native-esm/__tests__/native-esm.test.js @@ -247,17 +247,17 @@ test('imports from "data:text/javascript" URI with invalid data fail', async () test('imports from "data:application/wasm" URI not supported', async () => { await expect( async () => await import('data:application/wasm,96cafe00babe'), - ).rejects.toThrow('Unsupported MIME type'); + ).rejects.toThrow('WASM is currently not supported'); }); test('supports imports from "data:application/json" URI', async () => { - const data = await import('data:application/json,{foo: "bar"}'); - expect(data.default).toStrictEqual({foo: 'bar'}); + const data = await import('data:application/json,{"foo": "bar"}'); + expect(data.default).toEqual({foo: 'bar'}); }); test('supports static "data:" URI import', async () => { const module = await import('../staticDataImport.js'); - expect(module.value()).toStrictEqual({bar: {obj: 456}, foo: '123'}); + expect(module.value()).toEqual({bar: {obj: 456}, foo: '123'}); }); test('imports from "data:" URI is properly cached', async () => { diff --git a/e2e/native-esm/staticDataImport.js b/e2e/native-esm/staticDataImport.js index f69a8a4f4452..f26873dc7b48 100644 --- a/e2e/native-esm/staticDataImport.js +++ b/e2e/native-esm/staticDataImport.js @@ -5,7 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import bar from 'data:application/json,{obj: 456}'; +import bar from 'data:application/json,{"obj": 456}'; import {foo} from 'data:text/javascript,export const foo = "123"'; export function value() { diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index 1374924a9b3f..0ee7f60d0f61 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -594,33 +594,42 @@ export default class Runtime { throw new Error(`Invalid data URI encoding: ${encoding}`); } + let module; if (mime === 'application/json') { - code = 'export default ' + code; - } - - const module = new SourceTextModule(code, { - context, - identifier: specifier, - importModuleDynamically: async ( - specifier: string, - referencingModule: VMModule, - ) => { - invariant( - runtimeSupportsVmModules, - 'You need to run with a version of node that supports ES Modules in the VM API. See https://jestjs.io/docs/ecmascript-modules', - ); - const module = await this.resolveModule( - specifier, - referencingModule.identifier, - referencingModule.context, - ); + module = new SyntheticModule( + ['default'], + function () { + const obj = JSON.parse(code); + // @ts-expect-error: TS doesn't know what `this` is + this.setExport('default', obj); + }, + {context, identifier: specifier}, + ); + } else { + module = new SourceTextModule(code, { + context, + identifier: specifier, + importModuleDynamically: async ( + specifier: string, + referencingModule: VMModule, + ) => { + invariant( + runtimeSupportsVmModules, + 'You need to run with a version of node that supports ES Modules in the VM API. See https://jestjs.io/docs/ecmascript-modules', + ); + const module = await this.resolveModule( + specifier, + referencingModule.identifier, + referencingModule.context, + ); - return this.linkAndEvaluateModule(module); - }, - initializeImportMeta(meta: ImportMeta) { - meta.url = specifier; - }, - }); + return this.linkAndEvaluateModule(module); + }, + initializeImportMeta(meta: ImportMeta) { + meta.url = specifier; + }, + }); + } this._esmoduleRegistry.set(specifier, module); return module;