add test, update docs

This commit is contained in:
Simon Knott 2024-08-12 14:44:15 +02:00
parent 9a80386c7d
commit 62ff3fd736
No known key found for this signature in database
GPG key ID: 8CEDC00028084AEC
2 changed files with 46 additions and 2 deletions

View file

@ -319,8 +319,16 @@ export function resolveImportSpecifierExtension(resolved: string, isPathMapping:
break; // Do not try '' when a more specific extension like '.jsx' matched.
}
// Following TypeScript's path mapping logic, index files and package.json are not resolved in ESM.
// TypeScript does not interpret package.json for path mappings: https://www.typescriptlang.org/docs/handbook/modules/reference.html#paths-should-not-point-to-monorepo-packages-or-node_modules-packages
// After TypeScript path mapping, here's how directories with a `package.json` are resolved:
// - `package.json#exports` is not respected
// - `package.json#main` is respected only in CJS mode
// - `index.js` default is respected only in CJS mode
//
// More info:
// - https://www.typescriptlang.org/docs/handbook/modules/reference.html#paths-should-not-point-to-monorepo-packages-or-node_modules-packages
// - https://www.typescriptlang.org/docs/handbook/modules/reference.html#directory-modules-index-file-resolution
// - https://nodejs.org/dist/latest-v20.x/docs/api/modules.html#folders-as-modules
const shouldNotResolveDirectory = isPathMapping && isESM;
if (!shouldNotResolveDirectory && dirExists(resolved)) {

View file

@ -606,6 +606,42 @@ test('should import packages with non-index main script through path resolver',
expect(result.output).toContain(`foo=42`);
});
test('should not honor `package.json#main` field in ESM mode', async ({ runInlineTest }) => {
const result = await runInlineTest({
'app/pkg/main.ts': `
export const foo = 42;
`,
'app/pkg/package.json': `
{ "main": "main.ts" }
`,
'package.json': `
{ "name": "example-project", "type": "module" }
`,
'playwright.config.ts': `
export default {};
`,
'tsconfig.json': `{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"app/*": ["app/*"],
},
},
}`,
'example.spec.ts': `
import { foo } from 'app/pkg';
import { test, expect } from '@playwright/test';
test('test', ({}) => {
console.log('foo=' + foo);
});
`,
});
expect(result.exitCode).toBe(1);
expect(result.output).toContain(`Cannot find package 'app'`);
});
test('does not honor `exports` field after type mapping', async ({ runInlineTest }) => {
const result = await runInlineTest({
'app/pkg/main.ts': `