microsoft / microsoft/playwright

[Feature]: Support Node.js subpath imports (`package.json` `imports` field)

Open
#40,062 0 comments 19 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

P3-collecting-feedback
Dominant language
TypeScript
Stars
96.3k
Forks
6.5k
Avg merge
1d 6h
Merged PRs (30d)
180

Description

### 🚀 Feature Request

Playwright's module resolver does not resolve Node.js [subpath imports](https://nodejs.org/api/packages.html#subpath-imports), i.e. specifiers starting with `#` that are mapped via the `imports` field of `package.json`. Only `tsconfig.json` `paths` aliases are currently supported, as documented [here](https://playwright.dev/docs/test-typescript#tsconfig-path-mapping).

### Example

Given the following `package.json`:
```json
{
"imports": {
"#utils/*": "./src/utils/*.ts"
}
}
```

And a test file or config using:
```ts
// playwright.config.ts
import { getEnvVar } from '#utils/env';
```

Running `npx playwright test` fails with:
```
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/project/internals/e2e-tests/src/utils/env'
imported from /project/internals/e2e-tests/playwright.config.ts
at finalizeResolution (node:internal/modules/esm/resolve:275:11)
at moduleResolve (node:internal/modules/esm/resolve:865:10)
at defaultResolve (node:internal/modules/esm/resolve:991:11)
at nextResolve (node:internal/modules/esm/hooks:785:28)
at resolve (.../playwright@1.59.1/node_modules/playwright/lib/transform/esmLoader.js:39:24)
...
code: 'ERR_MODULE_NOT_FOUND'
```

The stack trace shows the failure originates in Playwright's own `esmLoader.js`.

### Motivation

Node.js subpath imports have been stable since [Node.js 14.6.0](https://nodejs.org/api/packages.html#subpath-imports). TypeScript added [auto-import support for subpath imports in 5.4](https://devblogs.microsoft.com/typescript/announcing-typescript-5-4/#auto-import-support-for-subpath-imports), and TypeScript 6.0 extended that further by [supporting the `#/` prefix syntax](https://devblogs.microsoft.com/typescript/announcing-typescript-6-0/) under `nodenext` and `bundler` `moduleResolution`. The TypeScript toolchain is clearly treating subpath imports as a first-class feature going forward.

Subpath imports are increasingly recommended over TSConfig `paths` for new projects, because they are handled natively by Node.js at runtime with no extra tooling or loader registration needed. They are also the only standard way to get import aliases in a plain JavaScript project, where TSConfig `paths` is not an option.

The current situation forces users into one of these workarounds:

- Duplicate all aliases in TSConfig `paths` as well, which is redundant and diverges from the Node.js runtime semantics.
- Pre-compile tests with `tsc` before running Playwright, which adds overhead and friction to the dev loop.

Neither is acceptable when the whole point of subpath imports is to avoid that duplication and stay close to Node.js semantics. This is particularly painful in monorepos where subpath imports are defined at the package level and are expected to work consistently across the whole toolchain.

I think that this is not a Babel transform concern, it is a module resolution concern, which is where TSConfig `paths` support already lives?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with Playwright's lib/transform/esmLoader.js, where the issue's stack trace places the failure, and compare its existing tsconfig.json paths resolution with Node.js package imports. Use the package.json and playwright.config.ts example to trace resolution of #utils/env. Done means the shown subpath import resolves when running npx playwright test without duplicating the alias in tsconfig.json.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
testing-qa, tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.