mirror of
https://github.com/microsoft/playwright.git
synced 2024-10-05 08:57:49 +03:00
fix(esm+tsconfig): allow mapped ts files in esm mode (#17862)
Fixes https://github.com/microsoft/playwright/issues/17840
This commit is contained in:
parent
f2685cab95
commit
c0e4caa604
@ -23,7 +23,7 @@ import { transformHook, resolveHook, belongsToNodeModules } from './transform';
|
||||
async function resolve(specifier: string, context: { parentURL?: string }, defaultResolve: Function) {
|
||||
if (context.parentURL && context.parentURL.startsWith('file://')) {
|
||||
const filename = url.fileURLToPath(context.parentURL);
|
||||
const resolved = resolveHook(filename, specifier);
|
||||
const resolved = resolveHook(true, filename, specifier);
|
||||
if (resolved !== undefined)
|
||||
specifier = url.pathToFileURL(resolved).toString();
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ const scriptPreprocessor = process.env.PW_TEST_SOURCE_TRANSFORM ?
|
||||
require(process.env.PW_TEST_SOURCE_TRANSFORM) : undefined;
|
||||
const builtins = new Set(Module.builtinModules);
|
||||
|
||||
export function resolveHook(filename: string, specifier: string): string | undefined {
|
||||
export function resolveHook(isModule: boolean, filename: string, specifier: string): string | undefined {
|
||||
if (builtins.has(specifier))
|
||||
return;
|
||||
const isTypeScript = filename.endsWith('.ts') || filename.endsWith('.tsx');
|
||||
@ -132,11 +132,21 @@ export function resolveHook(filename: string, specifier: string): string | undef
|
||||
if (value.includes('*'))
|
||||
candidate = candidate.replace('*', matchedPartOfSpecifier);
|
||||
candidate = path.resolve(tsconfig.absoluteBaseUrl, candidate.replace(/\//g, path.sep));
|
||||
for (const ext of ['', '.js', '.ts', '.mjs', '.cjs', '.jsx', '.tsx', '.cjs', '.mts', '.cts']) {
|
||||
if (fs.existsSync(candidate + ext)) {
|
||||
if (isModule) {
|
||||
const transformed = js2ts(candidate);
|
||||
if (transformed || fs.existsSync(candidate)) {
|
||||
if (keyPrefix.length > longestPrefixLength) {
|
||||
longestPrefixLength = keyPrefix.length;
|
||||
pathMatchedByLongestPrefix = candidate;
|
||||
pathMatchedByLongestPrefix = transformed || candidate;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const ext of ['', '.js', '.ts', '.mjs', '.cjs', '.jsx', '.tsx', '.cjs', '.mts', '.cts']) {
|
||||
if (fs.existsSync(candidate + ext)) {
|
||||
if (keyPrefix.length > longestPrefixLength) {
|
||||
longestPrefixLength = keyPrefix.length;
|
||||
pathMatchedByLongestPrefix = candidate;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -145,13 +155,17 @@ export function resolveHook(filename: string, specifier: string): string | undef
|
||||
if (pathMatchedByLongestPrefix)
|
||||
return pathMatchedByLongestPrefix;
|
||||
}
|
||||
if (specifier.endsWith('.js')) {
|
||||
const resolved = path.resolve(path.dirname(filename), specifier);
|
||||
if (resolved.endsWith('.js')) {
|
||||
const tsResolved = resolved.substring(0, resolved.length - 3) + '.ts';
|
||||
if (!fs.existsSync(resolved) && fs.existsSync(tsResolved))
|
||||
return tsResolved;
|
||||
}
|
||||
|
||||
if (isModule)
|
||||
return js2ts(path.resolve(path.dirname(filename), specifier));
|
||||
}
|
||||
|
||||
export function js2ts(resolved: string): string | undefined {
|
||||
const match = resolved.match(/(.*)(\.js|\.jsx|\.mjs)$/);
|
||||
if (match) {
|
||||
const tsResolved = match[1] + match[2].replace('j', 't');
|
||||
if (!fs.existsSync(resolved) && fs.existsSync(tsResolved))
|
||||
return tsResolved;
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,7 +211,7 @@ export function installTransform(): () => void {
|
||||
const originalResolveFilename = (Module as any)._resolveFilename;
|
||||
function resolveFilename(this: any, specifier: string, parent: Module, ...rest: any[]) {
|
||||
if (!reverted && parent) {
|
||||
const resolved = resolveHook(parent.filename, specifier);
|
||||
const resolved = resolveHook(false, parent.filename, specifier);
|
||||
if (resolved !== undefined)
|
||||
specifier = resolved;
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ test('should respect path resolver in experimental mode', async ({ runInlineTest
|
||||
},
|
||||
}`,
|
||||
'a.test.ts': `
|
||||
import { foo } from 'util/b.ts';
|
||||
import { foo } from 'util/b.js';
|
||||
const { test } = pwt;
|
||||
test('check project name', ({}, testInfo) => {
|
||||
expect(testInfo.project.name).toBe(foo);
|
||||
|
Loading…
Reference in New Issue
Block a user