layout icon indicating copy to clipboard operation
layout copied to clipboard

Adding DisplayObject to a container causes this error : Uncaught RangeError: Maximum call stack size exceeded at ContentController.createContent

Open seafloyd16 opened this issue 2 years ago • 13 comments

Why I get this error?

I am currently making an Electron app. Electron is basically uses commonjs so I run esbuild to get a cjs formatted bundle.

And here is my script for quick test.

const { Layout } = require('./layout');
const { Application, Graphics, Sprite, Text } = require('./pixi.min');

const app = new Application
(
    {
        resizeTo: window,
        background: 0xffffff
    }
);

$('#main').append(app.view);

let L = new Layout
(
    {
        id: 'root',
        content: new Text('This is a PixiJS text'), // This causes the error!
        styles:
        {
            background: 'black',
            position: 'center',
            borderRadius: 20,
            padding: 20,
            color: 'white',
        }
    }
);

L.eventMode = 'none';
L.refresh();
L.resize($('body').width(), $('body').height());
app.stage.addChild(L);

NodeJS v18.18.0 Electron v27.0.2

seafloyd16 avatar Oct 30 '23 12:10 seafloyd16

@seafloyd16

Under the hood. ContentController is checking the type of a given object, to decide how to proceed with it:

https://github.com/pixijs/layout/blob/e1d591bf8c86e59f6084afa676eb0ff27941c923/src/controllers/ContentController.ts#L268

So, maybe in electron it can not detect it proper way? Try to just pass 'This is a PixiJS text' instead of Text instance.

CyberDex avatar Oct 30 '23 13:10 CyberDex

Tried to reproduce this one on a normal env, and there is no issue here.

CyberDex avatar Oct 30 '23 13:10 CyberDex

So, when it is an instance of text, it should just add it there. In case if this is a layout config tree, it should go throughout it and parse -> add elements recursively. So if it recognises your Text instance as layout config, it can start trying to parse it and this could potentially end up in Maximum call stack error

CyberDex avatar Oct 30 '23 13:10 CyberDex

Hi, thank you for your replying and taking your time. I know that if I want a text, just type desired text without any constructor. It is working. But, as I said in the title, DisplayObject, like sprite and graphics are also causing the error.

So the code from "Usage" section in the full doc won't work. Usage

new Layout({
    content: {
        content: Sprite.from("bunny.png"),
        styles: {
            position: "center",
            maxWidth: "100%",
            minHeight: "100%",
        },
    },
    styles: {
        background: "red",
        position: "center",
        width: `100%`,
        height: `100%`,
    },
});

I tried to add a rectangle to a layout using addChild() and it was added, but the layout won't recalculate its size.

let rect = new Graphics();
rect.beginFill(0xffffff);
rect.drawRect(0, 0, 50, 50);
rect.endFill();

let L = new Layout
(
    {
        id: 'root',
        content:
        {
            id: 'contentA',
            content: {},
            styles:
            {
                background: 'gray',
                position: 'center',
                borderRadius: 20,
                padding: 20,
                color: 'white',
            }
        },
        styles:
        {
            background: 'black',
            position: 'center',
            borderRadius: 20,
            padding: 20,
            color: 'white',
        }
    }
);

L.getChildByID('contentA').addChild(rect);

seafloyd16 avatar Oct 30 '23 14:10 seafloyd16

OK, that means, I am right and it can not recognise the instances. I could try to take a look into it if you would create some repo with this basic setup, but I am not en expert in electron so can not promise I will be able to fix this.

CyberDex avatar Oct 30 '23 14:10 CyberDex

Thank you again. Exporting bundles with esbuild may itself be wrong. I gonna research more, and will change my app setup to support ESM, instead of CJS.

seafloyd16 avatar Oct 30 '23 15:10 seafloyd16

Don't know of the root cause is the same but I also got call stack exceeded (after upgrading to 0.3.4). After doing a little bit of digging I found that the check content instanceof Container in getContentType always returned false, even though I was sure that it in fact was a Container. That led med to believe I had some other interfering packages. I had pixi ui as well but didn't use it. As soon as I removed it things started working again.

I am not using electron by the way.

ViktorJakobsson avatar Oct 31 '23 10:10 ViktorJakobsson

Hmmm. Interesting discovery, do you think you could put it together in some repo where I can reproduce it and maybe fix?

CyberDex avatar Oct 31 '23 12:10 CyberDex

Don't know of the root cause is the same but I also got call stack exceeded (after upgrading to 0.3.4). After doing a little bit of digging I found that the check content instanceof Container in getContentType always returned false, even though I was sure that it in fact was a Container. That led med to believe I had some other interfering packages. I had pixi ui as well but didn't use it. As soon as I removed it things started working again.

I am not using electron by the way.

PixiJS UI is not installed in my project. Thank you anyway!

seafloyd16 avatar Oct 31 '23 12:10 seafloyd16

Tried to reproduce this one on a normal env, and there is no issue here.

Hi. Can you bundle PixiJS Layout to an IIFE script using esbuild by running command below and test your env with it please? I'm just curious that esbuild output a proper bundle or not.

npx esbuild --bundle src\index.ts --outfile=pixi-layout.js --format=iife --global-name=pixiLayout

The bundle format is IIFE so put a script tag to load the one in your html. index.html:

<script src="pixi.min.js"></script>
<script src="pixi-layout.js"></script>
<script src="index.js"></script>

And then put the script below and please tell me the script works or doesn't.

new pixiLayout.Layout({
    content: {
        content: new PIXI.Container(),
        styles: {
            position: "center",
            maxWidth: "100%",
            minHeight: "100%",
        },
    },
    styles: {
        background: "red",
        position: "center",
        width: `100%`,
        height: `100%`,
    },
});

seafloyd16 avatar Nov 01 '23 12:11 seafloyd16

got Maximum call stack size exceeded. Debugging shows content type is always object, so this is The issue I had in mind, will think how to improve that checks.

CyberDex avatar Nov 02 '23 08:11 CyberDex

got Maximum call stack size exceeded. Debugging shows content type is always object, so this is The issue I had in mind, will think how to improve that checks.

Thank you again, CyberDex. So, bundling is making things bad?

seafloyd16 avatar Nov 02 '23 11:11 seafloyd16

@seafloyd16 , sorry for late answer. This may be related to the way imports are happening. The build is made with rollup, so using option iife makes it use different imports (https://rollupjs.org/configuration-options/).

Also as a potential reason it can be 2 different pixi folders used, one is when building pixiLayout, other one is when you import pixi from the file directly, so obviously, even if it is the same versions instanceof will detect them as 2 separated instances, so the check fails. Probably instanceof may be replaced with some better checks here.

CyberDex avatar Dec 05 '23 18:12 CyberDex