Search code examples
typescriptpixi.jssveltekit

Pixi.js in SvelteKit gives a 'self is not defined' error only while building


As the title states, when using Pixi.js in SvelteKit, ONLY and ONLY while building the application, it will spit out a "self is not defined" error, and it traces back to the @pixi/settings module. I have tried every possible way that I know to fix this. First I used a shim to give it some dummy information, but that didn't work:


if (typeof window === 'undefined') {
    globalThis.window = {} as any;
}
if (typeof self === 'undefined') {
    globalThis.self = globalThis.window;
}
if (typeof document === 'undefined') {
    if (window.document) {
        globalThis.document = window.document;
    } else {
        globalThis.document = window.document = {
            createElement: (elementName: string) => {
                switch (elementName) {
                    case 'canvas':
                        return {
                            getContext: (contextName: string) => {
                                switch (contextName) {
                                    case 'webgl':
                                        return {
                                            getExtension: () => {}
                                        };
                                    case '2d':
                                        return {
                                            fillRect: () => {},
                                            drawImage: () => {},
                                            getImageData: () => {}
                                        };
                                }
                            }
                        };
                }
            }
        } as any;
    }
    if (typeof CanvasRenderingContext2D === 'undefined') {
        globalThis.CanvasRenderingContext2D = { prototype: {} };
    }
}
export {};

The shim gives all the necessary dummy informations and variables needed to run, but I guess it doesn't matter on build. Then I tried to import pixi.js dynamically onMount inside the code like so:

<script lang="ts">
    import '$utils/pixi-ssr-shim';
    import { onMount } from 'svelte';
    import App from './utils/App';
    import { run } from './seating-chart';

    let el: HTMLDivElement;

    onMount(async () => {
        //@ts-ignore
        const PIXI = await import('pixi.js');

        run(el, PIXI);

        window.addEventListener('resize', () => {
            App.app.destroy(true);
            App.app = null;
            App.viewport = null;

            run(el, PIXI);
        });
    });
</script>

<div class="flex items-center justify-around">
    <div bind:this={el} />
</div>


I also tried creating my own bundle of pixi.js like how pixijs.io/customize do, and that only creates another issue that I couldn't be bothered with.

So, I have no idea what to do to fix this, because I cannot just go around the error and run the program.


Solution

  • This was actually caused by the pixijs code having used self in their code and when the sveltekit compiler analyzes it, it errors out because nodejs doesn't have self as a variable, I have fixed this issue and created a pull request into the main branch of pixijs that will be released at 6.3.0.

    Here's the PR: https://github.com/pixijs/pixijs/pull/8050