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

Class definition order causes run-time exception #770

Closed
raijinsetsu opened this issue Feb 8, 2021 · 9 comments
Closed

Class definition order causes run-time exception #770

raijinsetsu opened this issue Feb 8, 2021 · 9 comments

Comments

@raijinsetsu
Copy link

raijinsetsu commented Feb 8, 2021

We have a Typescript module and are trying to use ESBuild to create a bundle and minify. When attempting to execute the minified output, Node throws an exception (minify turned off for debugging here):

var Model = class extends BaseModel {
                          ^

TypeError: Class extends value undefined is not a constructor or null
    at Object.<anonymous> (/home/lucas/meditech.com/webapi-server/server-components/model/dist/index.js:190:27)

When I look at index.js, I can see that this line appears BEFORE class BaseModel is defined. That's obviously wrong. This code works just fine when not bundled by ESBuild and I have not tried other bundles as-of-yet.

I am in the process of trying to create a minimal reproduction of the issue. For now, here are some tid-bits:

  • configuration: {bundle: true, entryPoints: ['src/index.ts'], minify: true, outfile: 'dist/index.js', platform: 'node', sourceMap: 'external', treeShaking: true}
@raijinsetsu
Copy link
Author

I am not having any luck reproducing the issue in a stand-alone project. If there are flags/edits I can make so that debugging information would be output, I can do that. However, I cannot share the original repository.

My thinking is that it has something to do with cyclic dependencies.

@raijinsetsu
Copy link
Author

I removed all cyclic dependencies but the issue is still there. I'm trying to review the esbuild code but I'm not very proficient in Go. I'm kind of at a dead end looking into this further.

@evanw
Copy link
Owner

evanw commented Feb 11, 2021

I'm sorry that this isn't working for you. Unfortunately I'm not able to solve this without more information.

One thought: are you using code splitting? Code splitting is still experimental and currently has a known ordering issue that I'm still working toward fixing.

@raijinsetsu
Copy link
Author

Hi Evan,
I am not using code splitting. My entire configuration is included in the original entry.

My thought is that, if these were the older style "function" type definitions instead, this would work out fine because the parent class would not need to be defined until the constructor on the derived class was actually called. That got me thinking that this ordering isn't handled by ESBuild at all, but, like I said before, I'm not proficient in Go so I cannot really make that determiniation.

@evanw
Copy link
Owner

evanw commented Mar 29, 2021

Closing because this is unactionable without a way for me to reproduce the issue.

@evanw evanw closed this as completed Mar 29, 2021
@Alex1990
Copy link

I came across the same error because of circular dependency. The reproduction is below.

src/Node.js

import { TextNode } from './TextNode'

export class Node {
  createTextNode() {
    return new TextNode()
  }
}

src/TextNode.js

import { Node } from './Node'

export class TextNode extends Node {}

src/index.js

export * from './Node'
export * from './TextNode'

Then, the content of bundle file:

// src/TextNode.js
// **At this time, Node is undefined**
var TextNode = class extends Node {
};

// src/Node.js
var Node = class {
  createTextNode() {
    return new TextNode();
  }
};
export {
  Node,
  TextNode
};

And, I use the rollup to bundle, it will output a warning:

$ rollup src/index.js --file rollup.bundle.js --format es

src/index.js → rollup.bundle.js...
(!) Circular dependency
src/Node.js -> src/TextNode.js -> src/Node.js
created rollup.bundle.js in 23ms

@evanw
Copy link
Owner

evanw commented Apr 17, 2021

But if you run that code in node natively (without bundling it with esbuild), you get the same error:

$ node index.js
export class TextNode extends Node {}
                              ^

ReferenceError: Cannot access 'Node' before initialization
    at TextNode.js:3:31
    at ModuleJob.run (internal/modules/esm/module_job.js:152:23)
    at async Loader.import (internal/modules/esm/loader.js:166:24)
    at async Object.loadESM (internal/process/esm_loader.js:68:5)

Since node itself crashes when you run your code, this is a problem with your code, not with esbuild. You need to fix the circular import in your code to get the code to run.

@Alex1990
Copy link

Yes, I posted the last comment for providing more detail.

@J-Cake
Copy link

J-Cake commented Jul 29, 2024

I'm facing a similar issue now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants