mirror of https://github.com/facebook/jest.git
fix: always load `.mjs` files via `import` (#15447)
This commit is contained in:
parent
1e60073a86
commit
43fedb5e05
|
@ -85,6 +85,7 @@
|
|||
- [**BREAKING**] `--testPathPattern` is now `--testPathPatterns`
|
||||
- [**BREAKING**] Specifying `testPathPatterns` when programmatically calling `watch` must be specified as `new TestPathPatterns(patterns)`, where `TestPathPatterns` can be imported from `@jest/pattern`
|
||||
- `[jest-reporters, jest-runner]` Unhandled errors without stack get correctly logged to console ([#14619](https://github.com/jestjs/jest/pull/14619))
|
||||
- `[jest-util]` Always load `mjs` files with `import` ([#15447](https://github.com/jestjs/jest/pull/15447))
|
||||
- `[jest-worker]` Properly handle a circular reference error when worker tries to send an assertion fails where either the expected or actual value is circular ([#15191](https://github.com/jestjs/jest/pull/15191))
|
||||
- `[jest-worker]` Properly handle a BigInt when worker tries to send an assertion fails where either the expected or actual value is BigInt ([#15191](https://github.com/jestjs/jest/pull/15191))
|
||||
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
const displayName = await Promise.resolve('Config from js file');
|
||||
|
||||
export default {
|
||||
displayName: 'Config from js file',
|
||||
displayName,
|
||||
testEnvironment: 'node',
|
||||
};
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
const displayName = await Promise.resolve('Config from mjs file');
|
||||
|
||||
export default {
|
||||
displayName: 'Config from mjs file',
|
||||
displayName,
|
||||
testEnvironment: 'node',
|
||||
};
|
||||
|
|
|
@ -26,6 +26,23 @@ jest
|
|||
...realFs,
|
||||
statSync: () => ({isDirectory: () => true}),
|
||||
};
|
||||
})
|
||||
.mock('jest-util', () => {
|
||||
const realUtil =
|
||||
jest.requireActual<typeof import('jest-util')>('jest-util');
|
||||
|
||||
return {
|
||||
...realUtil,
|
||||
requireOrImportModule: (filePath: string, interop = true) => {
|
||||
const result = require(filePath);
|
||||
|
||||
if (interop) {
|
||||
return realUtil.interopRequireDefault(result).default;
|
||||
}
|
||||
|
||||
return result;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
let root: string;
|
||||
|
|
|
@ -9,6 +9,39 @@ import {isAbsolute} from 'path';
|
|||
import {pathToFileURL} from 'url';
|
||||
import interopRequireDefault from './interopRequireDefault';
|
||||
|
||||
async function importModule(
|
||||
filePath: string,
|
||||
applyInteropRequireDefault: boolean,
|
||||
) {
|
||||
try {
|
||||
const moduleUrl = pathToFileURL(filePath);
|
||||
|
||||
// node `import()` supports URL, but TypeScript doesn't know that
|
||||
const importedModule = await import(
|
||||
/* webpackIgnore: true */ moduleUrl.href
|
||||
);
|
||||
|
||||
if (!applyInteropRequireDefault) {
|
||||
return importedModule;
|
||||
}
|
||||
|
||||
if (!importedModule.default) {
|
||||
throw new Error(
|
||||
`Jest: Failed to load ESM at ${filePath} - did you use a default export?`,
|
||||
);
|
||||
}
|
||||
|
||||
return importedModule.default;
|
||||
} catch (error: any) {
|
||||
if (error.message === 'Not supported') {
|
||||
throw new Error(
|
||||
`Jest: Your version of Node does not support dynamic import - please enable it or use a .cjs file extension for file ${filePath}`,
|
||||
);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export default async function requireOrImportModule<T>(
|
||||
filePath: string,
|
||||
applyInteropRequireDefault = true,
|
||||
|
@ -19,40 +52,21 @@ export default async function requireOrImportModule<T>(
|
|||
);
|
||||
}
|
||||
try {
|
||||
if (filePath.endsWith('.mjs')) {
|
||||
return importModule(filePath, applyInteropRequireDefault);
|
||||
}
|
||||
|
||||
const requiredModule = require(filePath);
|
||||
if (!applyInteropRequireDefault) {
|
||||
return requiredModule;
|
||||
}
|
||||
return interopRequireDefault(requiredModule).default;
|
||||
} catch (error: any) {
|
||||
if (error.code === 'ERR_REQUIRE_ESM') {
|
||||
try {
|
||||
const moduleUrl = pathToFileURL(filePath);
|
||||
|
||||
// node `import()` supports URL, but TypeScript doesn't know that
|
||||
const importedModule = await import(
|
||||
/* webpackIgnore: true */ moduleUrl.href
|
||||
);
|
||||
|
||||
if (!applyInteropRequireDefault) {
|
||||
return importedModule;
|
||||
}
|
||||
|
||||
if (!importedModule.default) {
|
||||
throw new Error(
|
||||
`Jest: Failed to load ESM at ${filePath} - did you use a default export?`,
|
||||
);
|
||||
}
|
||||
|
||||
return importedModule.default;
|
||||
} catch (innerError: any) {
|
||||
if (innerError.message === 'Not supported') {
|
||||
throw new Error(
|
||||
`Jest: Your version of Node does not support dynamic import - please enable it or use a .cjs file extension for file ${filePath}`,
|
||||
);
|
||||
}
|
||||
throw innerError;
|
||||
}
|
||||
if (
|
||||
error.code === 'ERR_REQUIRE_ESM' ||
|
||||
error.code === 'ERR_REQUIRE_ASYNC_MODULE'
|
||||
) {
|
||||
return importModule(filePath, applyInteropRequireDefault);
|
||||
} else {
|
||||
throw error;
|
||||
}
|
||||
|
|
22
yarn.lock
22
yarn.lock
|
@ -10555,8 +10555,8 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"express@npm:^4.17.3":
|
||||
version: 4.21.1
|
||||
resolution: "express@npm:4.21.1"
|
||||
version: 4.21.2
|
||||
resolution: "express@npm:4.21.2"
|
||||
dependencies:
|
||||
accepts: ~1.3.8
|
||||
array-flatten: 1.1.1
|
||||
|
@ -10577,7 +10577,7 @@ __metadata:
|
|||
methods: ~1.1.2
|
||||
on-finished: 2.4.1
|
||||
parseurl: ~1.3.3
|
||||
path-to-regexp: 0.1.10
|
||||
path-to-regexp: 0.1.12
|
||||
proxy-addr: ~2.0.7
|
||||
qs: 6.13.0
|
||||
range-parser: ~1.2.1
|
||||
|
@ -10589,7 +10589,7 @@ __metadata:
|
|||
type-is: ~1.6.18
|
||||
utils-merge: 1.0.1
|
||||
vary: ~1.1.2
|
||||
checksum: 5ac2b26d8aeddda5564fc0907227d29c100f90c0ead2ead9d474dc5108e8fb306c2de2083c4e3ba326e0906466f2b73417dbac16961f4075ff9f03785fd940fe
|
||||
checksum: 3aef1d355622732e20b8f3a7c112d4391d44e2131f4f449e1f273a309752a41abfad714e881f177645517cbe29b3ccdc10b35e7e25c13506114244a5b72f549d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -16032,11 +16032,11 @@ __metadata:
|
|||
linkType: hard
|
||||
|
||||
"nanoid@npm:^3.3.7":
|
||||
version: 3.3.7
|
||||
resolution: "nanoid@npm:3.3.7"
|
||||
version: 3.3.8
|
||||
resolution: "nanoid@npm:3.3.8"
|
||||
bin:
|
||||
nanoid: bin/nanoid.cjs
|
||||
checksum: d36c427e530713e4ac6567d488b489a36582ef89da1d6d4e3b87eded11eb10d7042a877958c6f104929809b2ab0bafa17652b076cdf84324aa75b30b722204f2
|
||||
checksum: dfe0adbc0c77e9655b550c333075f51bb28cfc7568afbf3237249904f9c86c9aaaed1f113f0fddddba75673ee31c758c30c43d4414f014a52a7a626efc5958c9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -17047,10 +17047,10 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"path-to-regexp@npm:0.1.10":
|
||||
version: 0.1.10
|
||||
resolution: "path-to-regexp@npm:0.1.10"
|
||||
checksum: ab7a3b7a0b914476d44030340b0a65d69851af2a0f33427df1476100ccb87d409c39e2182837a96b98fb38c4ef2ba6b87bdad62bb70a2c153876b8061760583c
|
||||
"path-to-regexp@npm:0.1.12":
|
||||
version: 0.1.12
|
||||
resolution: "path-to-regexp@npm:0.1.12"
|
||||
checksum: ab237858bee7b25ecd885189f175ab5b5161e7b712b360d44f5c4516b8d271da3e4bf7bf0a7b9153ecb04c7d90ce8ff5158614e1208819cf62bac2b08452722e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
|
Loading…
Reference in New Issue