undici: Unexpected token on class private field check with in operator

Bug Description

The issue arises from undici@6.7.0, which is believed to be caused by the PR https://github.com/nodejs/undici/pull/2743/files#diff-7d87ea2cf8b3c20e25ac9a785c4ae7603f4a8c3d7bf3a80f5fb46265f0dba078R776

 ⨯ ./node_modules/undici/lib/web/fetch/util.js
Module parse failed: Unexpected token (608:63)
|             // 5. If object is not a default iterator object for interface,
|             //    then throw a TypeError.
>             if (typeof this !== "object" || this === null || !(#target in this)) {
|                 throw new TypeError(`'next' called on an object that does not implement interface ${name} Iterator.`);
|             }

Import trace for requested module:
./node_modules/undici/lib/web/fetch/util.js
./node_modules/undici/lib/web/fetch/index.js
./node_modules/undici/index.js

Reproducible By

The issue can be replicated in any Next.js project by simply upgrading undici to version 6.7.0

Expected Behavior

Run without error

Logs & Screenshots

Environment

Additional context

About this issue

  • Original URL
  • State: closed
  • Created 4 months ago
  • Comments: 24 (20 by maintainers)

Most upvoted comments

Hey @fersan96 @HelaGone.

swc in Next.js doesn’t fully support the transformation of private properties and methods. I am using a temporary solution by integrating babel-loader with required plugins. Given that transforming code can slow down building times, only undici packages is included by the loader.

A small change for webpack config in next.config.js like below

    webpack: (config, { isServer }) => {
      config.module.rules.push({
        test: /\.(?:js|ts)$/,
        include: [/node_modules\/(undici)/],
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: ["next/babel"],
              plugins: [
                "@babel/plugin-transform-private-property-in-object",
                "@babel/plugin-transform-private-methods",
              ],
            },
          },
        ],
      });
      return config;
    },
  };


Also I reported these plugins to Next.js https://github.com/vercel/next.js/discussions/30174#discussioncomment-8793544, feel free to leave a comment and probably could speed up that.

Yep, I’m hitting the same error too. I’ll flag this with the Next.js folks and dig into it. It’s holding us up on updating undici for now. Thanks for the help! I’ll post any updates here and avoid any duplicate issues popping up.

@nicole0707 Hello, i hope you’re doing well, i would like to know what happend with this problem , is solved?

> $ yarn build
   ▲ Next.js 14.1.3

   Creating an optimized production build ...
Failed to compile.

./app/layout.tsx
Module parse failed: Unexpected token (11:12)
File was processed with these loaders:
 * ./node_modules/next/dist/build/webpack/loaders/next-flight-loader/index.js
 * ./node_modules/next/dist/build/webpack/loaders/next-swc-loader.js
You may need an additional loader to handle the result of these loaders.
|     #a;
|     a() {
>         if (#a in this) {
|         // do noting
|         }

Import trace for requested module:
./app/layout.tsx


> Build failed because of webpack errors

https://github.com/tsctx/nextjs-private-field-in-operator-bug

Definitely a problem with Next.js parser

> $ yarn build
   ▲ Next.js 14.1.3

   Creating an optimized production build ...
Failed to compile.

./app/layout.tsx
Module parse failed: Unexpected token (11:12)
File was processed with these loaders:
 * ./node_modules/next/dist/build/webpack/loaders/next-flight-loader/index.js
 * ./node_modules/next/dist/build/webpack/loaders/next-swc-loader.js
You may need an additional loader to handle the result of these loaders.
|     #a;
|     a() {
>         if (#a in this) {
|         // do noting
|         }

Import trace for requested module:
./app/layout.tsx


> Build failed because of webpack errors

https://github.com/tsctx/nextjs-private-field-in-operator-bug

If you cannot reproduce the problem without Next.js, then it is a problem with next.js.

Valid point seems like an issue with Nextjs and the clear context should be provided on how undici is used since Nextjs has a lot of moving parts as compared to working with Node plainly.

This is not a fundamental solution. Please report it Next.js and have the problem fixed.

Any chance we could get a bit more info on the perf impact?

Increasing the number of variables and adding try statements leads to extra overhead.

These are already slow and do not want to add even this small change.

typeof this !== 'object' || this === null || this.#target === undefined has passed all unit tests, is there other workarounds?🙏

class A {
  next () {
    let error = false
    try {
      if (typeof this !== 'object' || this === null) {
        error = true
      } else {
        this.#target
      }
    } catch (e) {
      error = true
    }
    if (error) {
      throw new TypeError(
        `'next' called on an object that does not implement interface ${name} Iterator.`
      )
    }
  }
}

This workaround is a violation of the specification because it throws an error with a false value.

Please provide a minimal viable code example.