Skip to content

Superclass replaced with null in production build #17711

@MattiasBuelens

Description

@MattiasBuelens

Bug report

What is the current behavior?

When building the following JavaScript file with Webpack in production mode, it generates invalid code that throws a TypeError at runtime:

var SuperClass = class {};

var UnusedClass = class extends SuperClass {
    constructor() {
      super();
    }
  },
  unusedVariable = new UnusedClass();

The resulting code looks like this:

new class extends(null){constructor(){super()}};

If the current behavior is a bug, please provide the steps to reproduce.

See https://github.com/MattiasBuelens/webpack-minify-issue for a full reproduction case, or open it on Stackblitz.

Run:

npm install
npm run build
npm run start

Then open the resulting app in a web browser. You should see the text "Running test...", and the following error will appear in the browser console:

Uncaught TypeError: Super constructor null of anonymous class is not a constructor
    at new document.body.innerText (main.js:1:81)
    at main.js:1:43

What is the expected behavior?

You should see the text "Test succeeded!" in the web browser. The resulting app should not throw a TypeError.

The app works fine when building in development mode, so changing mode to "development" in webpack.config.js demonstrates the expected correct behavior.

Other relevant information:
webpack version: 5.88.2
Node.js version: 18.18.0
Operating System: Windows 11 Pro 22H2 (build 22621.2283)
Additional tools: N/A

Initial investigation:
If you set optimization.minimize = false, then you get:

/******/ (() => { // webpackBootstrap
var __webpack_exports__ = {};

var SuperClass = class {};

var UnusedClass = class extends (/* unused pure expression or super */ null && (SuperClass)) {
    constructor() {
      super();
    }
  },
  unusedVariable = new UnusedClass();

/******/ })()
;

The "unused pure expression or super" comes from PureExpressionDependency.js, so the bug is probably somewhere around there.

Also interesting: if you split the variable declaration for UnusedClass and unusedVariable into two separate var statements, the bug does not show up.

var SuperClass = class {};

var UnusedClass = class extends SuperClass {
    constructor() {
        super();
    }
};
var unusedVariable = new UnusedClass();

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions