Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ReferenceError: __name is not defined #113

Open
Uninen opened this issue Oct 6, 2022 · 25 comments
Open

ReferenceError: __name is not defined #113

Uninen opened this issue Oct 6, 2022 · 25 comments
Labels

Comments

@Uninen
Copy link

Uninen commented Oct 6, 2022

Bug description

I'm trying to use Playwright screenshot function w/ tsx from command line. This has worked in previous versions and works with tsm but doesn't work w/ tsx.

Reproduction

// test.ts

import { chromium } from 'playwright-chromium'
;(async () => {
  const url = 'https://www.unessa.net'

  const browser = await chromium.launch({
    headless: true,
  })
  const context = await browser.newContext()
  const page = await context.newPage()

  await page.goto(url)
  await page.screenshot({
    path: 'test-screenshot.png',
    fullPage: true,
  })

  await browser.close()
})()

Runing npx tsx src/testfn.ts produces following error:

page.screenshot: ReferenceError: __name is not defined
    at eval (eval at evaluate (:190:30), <anonymous>:1:102)
    at UtilityScript.evaluate (<anonymous>:192:17)
    at UtilityScript.<anonymous> (<anonymous>:1:44)
=========================== logs ===========================
taking page screenshot
============================================================
    at null.<anonymous> (/../test.ts:12:14)

Environment

<!--
  Run and paste the output of:
  
  npx envinfo --system --npmPackages tsx --binaries

-->

  System:
    OS: macOS 12.6
    CPU: (8) arm64 Apple M1
    Memory: 83.13 MB / 16.00 GB
    Shell: 5.8.1 - /bin/zsh
  Binaries:
    Node: 16.15.1 - ~/.nvm/versions/node/v16.15.1/bin/node
    Yarn: 1.22.19 - /opt/homebrew/bin/yarn
    npm: 8.11.0 - ~/.nvm/versions/node/v16.15.1/bin/npm
    Watchman: 2022.09.19.00 - /opt/homebrew/bin/watchman
  npmPackages:
    tsx: 3.9.0 => 3.9.0 


### Can you contribute a fix?

- [ ] I’m interested in opening a pull request for this issue.
@Uninen Uninen added bug Something isn't working pending triage labels Oct 6, 2022
@privatenumber
Copy link
Owner

I think this is likely due to minifyIdentifiers being previously enabled, but it should be fixed now.

Can you check what version of @esbuild-kit/core-utils you have installed?

npm ls @esbuild-kit/core-utils

Make sure it's v2.3.2.

If it's the latest version, please provide your reproduction in a repository so I can install it with the exact environment.

@Uninen
Copy link
Author

Uninen commented Oct 10, 2022

Yes, the @esbuild-kit/core-utils version is 2.3.2. Pushed a small repro here: https://github.com/Uninen/tsx-issue-113-repro

@privatenumber
Copy link
Owner

Thanks for the reproduction. This is happening because esbuild's --keep-names option applies __name to functions to preserve the original name. The bug occurs when playwright stringifies the functions and evals them without the __name declaration.

This is a stated limitation so I wouldn't consider it a bug.

It probably works with tsm because it doesn't have --keep-names enabled, but it's necessary to preserve certain functionality in case esbuild renames variables, which can happen with variable shadowing.

Example

https://hyrious.me/esbuild-repl/?version=0.15.10&mode=transform&input=function+fn%28%29+%7B%0A%0A++function+fn%28%29+%7B%7D%0A++console.log%28fn.name+%3D%3D%3D+%27fn%27%29+%2F%2F+should+be+true%0A%7D&options=--keep-names

In this example, the inner fn is renamed to fn2. Without --keep-names, the assertion inside fails.


To fix this problem, I filed a feature request to only apply __name when the function is actually renamed: evanw/esbuild#2605

Alternatively, I can also shim globalThis.eval to always include a declaration for __name. However, it's a pretty frail solution that can break as soon as the variable __name is declared in user-code.

@CircleCurve

This comment was marked as resolved.

@privatenumber

This comment was marked as resolved.

@CircleCurve

This comment was marked as off-topic.

@privatenumber
Copy link
Owner

Yep, hence the blocked tag on this Issue.

@loynoir
Copy link

loynoir commented Apr 24, 2023

reproduce.mts

// @ts-check
import playwright from 'playwright-core'
const browser = await playwright.firefox.launch()
const browserContext = await browser.newContext()
const page = await browserContext.newPage()
await page.goto('http://127.0.0.1:1234/')
await page.waitForFunction('() => true')
await page.close()
await browserContext.close()
await browser.close()
node:internal/process/esm_loader:97
    internalBinding('errors').triggerUncaughtException(
                              ^

page.waitForFunction: __name is not defined
@debugger eval code line 195 > eval:1:95
evaluate@debugger eval code:197:17
@debugger eval code:1:44

    at <anonymous> (/path/to/reproduce.mts:7:12) {
  name: 'Error'
}

Node.js v18.15.0

@privatenumber

  • Are there any workarounds?
  • Can you provide a code, generated by esbuild, with same underlying problem, throws __name is not defined?
  • Seems esbuild has low interest to fix, does swc have same underlying problem? What about change tsx to use swc?

@loynoir
Copy link

loynoir commented Apr 24, 2023

Workaround, using ts-node, swc seems does not have this problem.

But ts-node seems does not support tsconfig.paths yet.


If you are using typescript 5.0, you may see related TypeStrong/ts-node#2000

$ npm exec -- tsc --showConfig > tsconfig.tsnode.json
$ npm exec -- ts-node --project tsconfig.tsnode.json --esm --swc ./reproduce.mts && echo OK
OK

But I'm still curious about what is the esbuild underlying problem, very appreciated for any explanation.

@loynoir
Copy link

loynoir commented Apr 26, 2023

Workaround updated

  1. Use --loader @esbuild-kit/esm-loader, which support tsconfig.paths, support typescript 5.0 tsconfig.extends array.
$ node --loader @esbuild-kit/esm-loader ./reproduce.mts && echo OK
(node:618326) ExperimentalWarning: Custom ESM Loaders is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
OK
  1. Use ts-node, which does not support tsconfig.paths, does not support typescript 5.0 tsconfig.extends array.
$ npm exec -- tsc --showConfig > tsconfig.tsnode.json
$ npm exec -- ts-node --project tsconfig.tsnode.json --esm --swc ./reproduce.mts && echo OK
OK

@privatenumber
Copy link
Owner

But I'm still curious about what is the esbuild underlying problem, very appreciated for any explanation.

Read #113 (comment)

@loynoir
Copy link

loynoir commented Apr 26, 2023

@privatenumber

Read #113 (comment)

I read before I said that.

But I don't understand how ReferenceError: __name is not defined is generated.


I filed a feature request to only apply __name when the function is actually renamed

I think should filed with BUG, with a small example throws ReferenceError: __name is not defined.

If a bundler generate different runtime output, when minify: false, I think it must be a BUG.

Besides, see #228, @esbuild-kit/esm-loader works fine.

So, seems it is a tsx bug, not esbuild bug.

@privatenumber
Copy link
Owner

It's kind of both.

  • tsx doesn't need to apply esbuild to all files but it currently does.
  • esbuild doesn't need to apply __name to all functions but it currently does.

@jd-solanki

This comment was marked as off-topic.

@privatenumber
Copy link
Owner

This specific problem is blocked by esbuild—out of my hands.

However, the 2 issues under "Optimize dependency transformations" on the Roadmap will address this from happening in dependencies.

@jd-solanki

This comment was marked as off-topic.

@privatenumber

This comment was marked as off-topic.

@privatenumber
Copy link
Owner

privatenumber commented Nov 6, 2023

The specific problem with playwright-core will be fixed via #365.

However, I'll leave this open because it's not completely fixed for all cases (e.g a dependency module that uses both ESM/TypeScript and eval()).

@vanya2h

This comment was marked as off-topic.

@privatenumber

This comment was marked as off-topic.

@niieani

This comment has been minimized.

@privatenumber
Copy link
Owner

With https://github.com/privatenumber/tsx/releases/tag/v4.0.0 released, this will likely no longer be an issue in the majority of cases.

Hope it works well for yall!

Keeping this issue open but labelled "Blocked" because the root issue is in esbuild.

@cjroebuck

This comment was marked as off-topic.

@privatenumber

This comment was marked as off-topic.

@privatenumber
Copy link
Owner

privatenumber commented Dec 13, 2023

Locking this thread since the problem is well-understood, and further investigation isn't needed.

The issue is blocked by evanw/esbuild#2605

Please avoid commenting "bump" or "please fix".
Instead, contribute constructively with research & PRs.

Repository owner locked and limited conversation to collaborators Dec 13, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

8 participants