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
65.69k stars 3.58k forks source link

[BUG] dynamic import of ESM results in ERR_REQUIRE_ESM #17075

Closed Janpot closed 3 months ago

Janpot commented 2 years ago

Context:

Code Snippet

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

test("dynamic import of ESM", async ({}) => {
  const { default: getPort } = await import("get-port");
  console.log(await getPort());
});

Describe the bug

From the node.js docs

Dynamic import() is supported in both CommonJS and ES modules. In CommonJS modules it can be used to load ES modules.

Yet, trying to load an ESM only package like get-port with a dynamic import statement fails with the error:

Error [ERR_REQUIRE_ESM]: require() of ES Module .../node_modules/get-port/index.js from .../tests/example.spec.ts not supported.
    Instead change the require of index.js in .../tests/example.spec.ts to a dynamic import() which is available in all CommonJS modules.

It's complaining I'm trying to use require to load an ESM only module, but as can be seen in the snippet, it's an import().

ilanb1996 commented 2 years ago

had a very similar issue, had to hardcode "@playwright/test": "1.22.2", in my package.json

dgozman commented 2 years ago

@Janpot This indeed does not work. The workaround is to either not use dynamic imports, or set "type": "module" in your package.json. Perhaps in the future we'll make it work out of the box.

frontsideair commented 1 year ago

I also suffer from this, many npm packages are moving to ESM only and using type: module makes it very hard in my case, since I have some imports to my code and requires me to turn everything to ESM.

It would be very much appreciated if this worked out of the box, or there was a workaround to avoid transpilation (I'm assuming there must be), as I like Playwright a lot and have been using it happily for a long time.

frontsideair commented 1 year ago

I have a pretty robust workaround, which might be helpful to others as well. The workaround uses esbuild, but could work with other tools.

  1. Pull all ESM dependencies in a file like this.
    
    // deps.ts
    import findCacheDir from "find-cache-dir";
    import getPort from "get-port";

export { findCacheDir, getPort };


2. Install esbuild and add a pretest script.
```json
"pretest": "esbuild --platform=node deps.ts --bundle --outfile=deps.bundle.js",
  1. Depend on deps.bundle in tests.
    import { findCacheDir, getPort } from "./deps.bundle";

If the dependencies get too large, you may get a warning like this and lose some Playwright features.

[BABEL] Note: The code generator has deoptimised the styling of /path/to/deps.bundle.js as it exceeds the max of 500KB.

This is the best I could do given the circumstances, let me know if you have a better solution.

D4N14L commented 1 year ago

@frontsideair curious what features are lost when that error appears? From what I understand, it's largely just a complaint from Babel that can be ignored.

frontsideair commented 1 year ago

It's been a while, but IIRC you lose the nice error messages when a test fails, that shows the test code that failed as a snippet.

kodermax commented 9 months ago

Bump. I would like to connect TRPC to the project.

import { createTRPCProxyClient, httpBatchLink } from '@trpc/client';
import type { AppRouter } from '@agent-b2b/trpc/src/server/routers';

export default async function setupTrpcClient() {
  const { default: superjson } = await import('superjson');
  return createTRPCProxyClient<AppRouter>({
    transformer: superjson,
    links: [
      httpBatchLink({
        url: `http://localhost:2022`,
      }),
    ],
  });
}
olayway commented 5 months ago

I have the same issue

matthew-dean commented 3 months ago

Playwright doesn't support ES moduels?? 🤔

foxaltus commented 4 weeks ago

So what, does https://github.com/microsoft/playwright/pull/31285 fixes it in v1.45.0?

I just tried using Component Testing with v1.46.1 and got this error right away:

> playwright test -c playwright-ct.config.ts

Error: require() of ES Module [...]\node_modules\.pnpm\@mdx-js+react@2.3.0_react@18.2.0\node_modules\@mdx-js\react\index.js from [...]\node_modules\.pnpm\@theme-ui+mdx@0.14.7_@emotion+react@11.11.4_@types+react@18.0.28_react@18.2.0__@mdx-js+react@_mbpdk4bezv7srjm4c3ytb2koyi\node_modules\@theme-ui\mdx\dist\theme-ui-mdx.cjs.dev.js not supported.
Instead change the require of index.js in [...]\node_modules\.pnpm\@theme-ui+mdx@0.14.7_@emotion+react@11.11.4_@types+react@18.0.28_react@18.2.0__@mdx-js+react@_mbpdk4bezv7srjm4c3ytb2koyi\node_modules\@theme-ui\mdx\dist\theme-ui-mdx.cjs.dev.js to a dynamic import() which is available in all CommonJS modules.