import.meta.resolve support (#14930)

Co-authored-by: Simen Bekkhus <sbekkhus91@gmail.com>
This commit is contained in:
Grant A. Cheadle 2024-03-03 06:46:27 -08:00 committed by GitHub
parent 0e8030536d
commit 442c7f692e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 56 additions and 23 deletions

View File

@ -21,6 +21,7 @@
- `[jest-mock]` Add support for the Explicit Resource Management proposal to use the `using` keyword with `jest.spyOn(object, methodName)` ([#14895](https://github.com/jestjs/jest/pull/14895))
- `[jest-runtime]` Exposing new modern timers function `jest.advanceTimersToFrame()` from `@jest/fake-timers` ([#14598](https://github.com/jestjs/jest/pull/14598))
- `[jest-runtime]` Support `import.meta.filename` and `import.meta.dirname` (available from [Node 20.11](https://nodejs.org/en/blog/release/v20.11.0)) ([#14854](https://github.com/jestjs/jest/pull/14854))
- `[jest-runtime]` Support `import.meta.resolve` ([#14930](https://github.com/jestjs/jest/pull/14930))
- `[@jest/schemas]` Upgrade `@sinclair/typebox` to v0.31 ([#14072](https://github.com/jestjs/jest/pull/14072))
- `[@jest/types]` `test.each()`: Accept a readonly (`as const`) table properly ([#14565](https://github.com/jestjs/jest/pull/14565))
- `[jest-snapshot]` [**BREAKING**] Add support for [Error causes](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause) in snapshots ([#13965](https://github.com/facebook/jest/pull/13965))

View File

@ -31,6 +31,7 @@ test('should have correct import.meta', () => {
dirname: expect.any(String),
filename: expect.any(String),
jest: expect.anything(),
resolve: expect.any(Function),
url: expect.any(String),
});
expect(import.meta.jest).toBe(jestObject);
@ -56,6 +57,16 @@ test('should have correct import.meta', () => {
true,
);
}
expect(
import.meta
.resolve('colors')
.endsWith('jest/e2e/native-esm/node_modules/colors/lib/index.js'),
).toBe(true);
expect(
import.meta
.resolve('./native-esm.test')
.endsWith('jest/e2e/native-esm/__tests__/native-esm.test.js'),
).toBe(true);
});
test('should double stuff', () => {
@ -68,6 +79,7 @@ test('should support importing node core modules', () => {
expect(JSON.parse(readFileSync(packageJsonPath, 'utf8'))).toEqual({
devDependencies: {
colors: '^1.4.0',
'discord.js': '14.3.0',
'iso-constants': '^0.1.2',
yargs: '^17.5.1',

View File

@ -4,6 +4,7 @@
"isolated-vm": "^4.6.0"
},
"devDependencies": {
"colors": "^1.4.0",
"discord.js": "14.3.0",
"iso-constants": "^0.1.2",
"yargs": "^17.5.1"

View File

@ -333,6 +333,13 @@ __metadata:
languageName: node
linkType: hard
"colors@npm:^1.4.0":
version: 1.4.0
resolution: "colors@npm:1.4.0"
checksum: 98aa2c2418ad87dedf25d781be69dc5fc5908e279d9d30c34d8b702e586a0474605b3a189511482b9d5ed0d20c867515d22749537f7bc546256c6014f3ebdcec
languageName: node
linkType: hard
"cross-spawn@npm:^7.0.0":
version: 7.0.3
resolution: "cross-spawn@npm:7.0.3"
@ -1087,6 +1094,7 @@ __metadata:
version: 0.0.0-use.local
resolution: "root-workspace-0b6124@workspace:."
dependencies:
colors: ^1.4.0
discord.js: 14.3.0
iso-constants: ^0.1.2
isolated-vm: ^4.6.0

View File

@ -518,12 +518,26 @@ export default class Runtime {
return this.linkAndEvaluateModule(module);
},
initializeImportMeta: (meta: JestImportMeta) => {
meta.url = pathToFileURL(modulePath).href;
const metaUrl = pathToFileURL(modulePath).href;
meta.url = metaUrl;
// @ts-expect-error Jest uses @types/node@16. Will be fixed when updated to @types/node@20.11.0
meta.filename = fileURLToPath(meta.url);
meta.filename = modulePath;
// @ts-expect-error Jest uses @types/node@16. Will be fixed when updated to @types/node@20.11.0
meta.dirname = path.dirname(meta.filename);
meta.dirname = path.dirname(modulePath);
// @ts-expect-error It should not be async. Will be fixed when updated to @types/node@20.11.0
meta.resolve = (specifier, parent = metaUrl) => {
const parentPath = fileURLToPath(parent);
const resolvedPath = this._resolver.resolveModule(
parentPath,
specifier,
{conditions: this.esmConditions},
);
return pathToFileURL(resolvedPath).href;
};
let jest = this.jestObjectCaches.get(modulePath);
@ -1466,28 +1480,25 @@ export default class Runtime {
if (module) {
return module;
}
} else {
const {paths} = options;
if (paths) {
for (const p of paths) {
const absolutePath = path.resolve(from, '..', p);
const module = this._resolver.resolveModuleFromDirIfExists(
absolutePath,
moduleName,
// required to also resolve files without leading './' directly in the path
{conditions: this.cjsConditions, paths: [absolutePath]},
);
if (module) {
return module;
}
}
throw new Resolver.ModuleNotFoundError(
`Cannot resolve module '${moduleName}' from paths ['${paths.join(
"', '",
)}'] from ${from}`,
} else if (options.paths) {
for (const p of options.paths) {
const absolutePath = path.resolve(from, '..', p);
const module = this._resolver.resolveModuleFromDirIfExists(
absolutePath,
moduleName,
// required to also resolve files without leading './' directly in the path
{conditions: this.cjsConditions, paths: [absolutePath]},
);
if (module) {
return module;
}
}
throw new Resolver.ModuleNotFoundError(
`Cannot resolve module '${moduleName}' from paths ['${options.paths.join(
"', '",
)}'] from ${from}`,
);
}
try {