Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

import.meta.resolve support #14930

Merged
merged 11 commits into from
Mar 3, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 23 additions & 1 deletion e2e/native-esm/__tests__/native-esm.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ import staticImportedStatefulWithQuery from '../stateful.mjs?query=1';
import staticImportedStatefulWithAnotherQuery from '../stateful.mjs?query=2';
/* eslint-enable */

test('should have correct import.meta', () => {
test('should have correct import.meta', async () => {
expect(typeof require).toBe('undefined');
expect(typeof jest).toBe('undefined');
expect(import.meta).toEqual({
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);
Expand All @@ -46,6 +47,16 @@ test('should have correct import.meta', () => {
expect(import.meta.dirname.endsWith('\\e2e\\native-esm\\__tests__')).toBe(
true,
);
expect(
(await import.meta.resolve('colors')).endsWith(
'\\jest\\e2e\\native-esm\\node_modules\\colors\\lib\\index.js',
),
).toBe(true);
expect(
(await import.meta.resolve('./native-esm.test')).endsWith(
'\\jest\\e2e\\native-esm\\__tests__\\native-esm.test.js',
),
).toBe(true);
} else {
expect(
import.meta.filename.endsWith(
Expand All @@ -55,6 +66,16 @@ test('should have correct import.meta', () => {
expect(import.meta.dirname.endsWith('/e2e/native-esm/__tests__')).toBe(
true,
);
expect(
(await import.meta.resolve('colors')).endsWith(
'jest/e2e/native-esm/node_modules/colors/lib/index.js',
),
).toBe(true);
expect(
(await import.meta.resolve('./native-esm.test')).endsWith(
'jest/e2e/native-esm/__tests__/native-esm.test.js',
),
).toBe(true);
}
});

Expand All @@ -68,6 +89,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',
Expand Down
1 change: 1 addition & 0 deletions e2e/native-esm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
8 changes: 8 additions & 0 deletions e2e/native-esm/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Expand Down
68 changes: 48 additions & 20 deletions packages/jest-runtime/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,37 @@ export default class Runtime {
// @ts-expect-error Jest uses @types/node@16. Will be fixed when updated to @types/[email protected]
meta.dirname = path.dirname(meta.filename);

meta.resolve = async (
CheadleCheadle marked this conversation as resolved.
Show resolved Hide resolved
specifier: string,
parent?: string | URL,
): Promise<string> => {
let filename: string;

if (typeof parent === 'string') {
// Check if parent is a valid file URL
if (parent.startsWith('file:///')) {
filename = path.resolve(fileURLToPath(parent), specifier);
} else {
// Parent is a non-URL string; treat as a file path
filename = path.resolve(parent, specifier);
}
} else {
// No valid parent provided fallback to module's URL
filename = modulePath;
}

const resolvedPath = await this._resolveModule(
filename,
specifier,
);

// Convert the resolved path back to a URL if parent was originally a URL otherwise return the path
return typeof parent === 'string' &&
parent.startsWith('file:///')
? pathToFileURL(resolvedPath).href
: resolvedPath;
};

let jest = this.jestObjectCaches.get(modulePath);

if (!jest) {
Expand Down Expand Up @@ -1466,28 +1497,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 {
Expand Down
Loading