microsoft / playwright

Playwright is a framework for Web Testing and Automation. It allows testing Chromium, Firefox and WebKit with a single API.
https://playwright.dev
Apache License 2.0
66.06k stars 3.61k forks source link

[BUG] require of ES Module not supported though using import-statement #14371

Closed LisBerndt closed 2 years ago

LisBerndt commented 2 years ago

Relating to my yesterday´s question I executed some tries. - I coded my package in javascript hoping to get it finally run, but it fails as well.

Context:

Code Snippet

The index.mjs of my custom package simply contains that:

let Provider = null
export { Provider };

Describe the bug

After publishing and installing my custom package, importing into my fixture by import { Provider } from [package] fails: Error [ERR_REQUIRE_ESM]: require() of ES Module [...]\index.mjs not supported. Instead change the require of [...]\index.mjs to a dynamic import() which is available in all CommonJS modules

Note that, only the import-statement, the error states that I was using require!

pavelfeldman commented 2 years ago

The issue at hand is that should you decide to make your module ESM-only, you can only depend on it from within other ESM modules. So you should convert your playwright project into ESM via setting type: 'module' in package.json. That's going to make everything into ESM, which is not necessarily what you want - ESM interoperability is in its early days in Node.

You probably want to make your reusable module a regular CJS module, compile TS into JS there, export types via d.ts, etc. Or alternatively, you can use baseDir and paths in tsconfig to import it as source in your dependent module.

LisBerndt commented 2 years ago

The issue at hand is that should you decide to make your module ESM-only, you can only depend on it from within other ESM modules. So you should convert your playwright project into ESM via setting type: 'module' in package.json. That's going to make everything into ESM, which is not necessarily what you want - ESM interoperability is in its early days in Node.

That was one of my earlier tries. But doing so, I get: /playwright.config.ts:1 import { PlaywrightTestConfig } from "@playwright/test"; ^^^^^^^^^^^^^^^^^^^^ SyntaxError: The requested module '@playwright/test' does not provide an export named 'PlaywrightTestConfig' And so I reverted that, fearing to provocate endless subsequent errors within the Playwright project.

LisBerndt commented 2 years ago

Ok, I finally got it work. Refactored my custom package from import- to require-statement, so totally ESM-free. Not the finest solution, in my opinion :-/ (I'm looking forward to times, when the js-developers resolve the pitfalls concerning the module types and present a consolidated approach.)

pavelfeldman commented 2 years ago

import { PlaywrightTestConfig } from "@playwright/test";

Because PlaywrightTestConfig is a type, not a class, you should do:

import type { PlaywrightTestConfig } from "@playwright/test";

or

import { type PlaywrightTestConfig } from "@playwright/test";

i23591326 commented 2 years ago

I have a large code base with lots of interfaces and classes imports mixed together that I have to migrate to ESM experimental build because of Angular 13, 14 dropped CJS support. I assume it's not possible to make playwright-test not to fail because of such issues, so maybe there is any easy way of auto-fixing such imports? What I mean exactly is replacing import {InterfaceA, ClassB} from 'whereever'; with import type {InterfaceA} from 'whereever; and import {ClassB} from 'whereever';`

My team has been struggling with whole playwright-test ESM migration for weeks already trying to pre-build typescript tests sources the way playwright-test would run with no luck, and I guess I just going to rewrite the whole code base manually, but maybe this would help the future generations not to struggle that much.

i23591326 commented 2 years ago

^ Found the consistent-type-imports eslint plugin with --fix available that helps a lot. https://typescript-eslint.io/rules/consistent-type-imports/ https://stackoverflow.com/questions/71080256/is-there-a-way-to-automatically-fix-import-type-errors-on-typescript-when-usin