webpackjestjsphaser-frameworkpixi.js

Jest Test Fails with "ReferenceError: PIXI is not defined" in Phaser-CE Project


I am using the phaser-ce version 2.20.0 in my project. Although being aware of the newer phaser version, I have to stick to the mentioned CE (community edition) version.

When I run a simple test written with Jest, the test suite fails with the following error:

ReferenceError: PIXI is not defined

(PixiJS (commonly referred to as Pixi) is a 2D graphics rendering using within Phaser.)

Here is my setup:

Project Structure:

phaser-jest-project/
│
├── dist/
├── src/
│   ├── index.js
│   └── game.js
├── test/
│   └── game.test.js
├── .babelrc
├── jest.config.js
├── package.json
└── webpack.config.js

package.json:

{
  "name": "phaser-ce-jest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "webpack serve --open",
    "build": "webpack",
    "test": "jest"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "phaser-ce": "^2.20.0"
  },
  "devDependencies": {
    "@babel/core": "^7.25.2",
    "@babel/preset-env": "^7.25.3",
    "@jest/globals": "^29.7.0",
    "babel-jest": "^29.7.0",
    "babel-loader": "^9.1.3",
    "expose-loader": "^5.0.0",
    "jest": "^29.7.0",
    "jest-environment-jsdom": "^29.7.0",
    "webpack": "^5.93.0",
    "webpack-cli": "^5.1.4",
    "webpack-dev-server": "^5.0.4"
  }
}

webpack.config.js:

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['@babel/preset-env'],
          },
        },
      },
    ],
  },
  devServer: {
    contentBase: path.resolve(__dirname, 'dist'),
    compress: true,
    port: 9000,
  },
};

.babelrc:

{
  "presets": ["@babel/preset-env"]
}

src/index.js:

import 'pixi';
import 'p2';
import Phaser from 'phaser';
import { createGame } from './game';

const game = createGame();

src/game.js:

import 'pixi';
import 'p2';
import Phaser from 'phaser';

export function createGame() {
    const game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload, create, update });

    function preload() {
        // Load assets
    }

    function create() {
        // Initialize game
    }

    function update() {
        // Game loop
    }

    return game;
}

test/game.test.js:

import { createGame } from '../src/game';
import { it, expect } from '@jest/globals';

it('game should be created', () => {
    const game = createGame();
    expect(game).toBeDefined();
});

jest.config.js:

const path = require('path');

module.exports = {
    moduleNameMapper: {
        '^pixi$': path.join(__dirname, 'node_modules/phaser-ce/build/custom/pixi.js'),
        '^p2$': path.join(__dirname, 'node_modules/phaser-ce/build/custom/p2.js'),
        '^phaser$': path.join(__dirname, 'node_modules/phaser-ce/build/custom/phaser-split.js'),
    },
    transform: {
        '^.+\\.js$': 'babel-jest'
    },
    testEnvironment: 'jest-environment-jsdom'
};

Question:

How can I resolve the "ReferenceError: PIXI is not defined" error when running Jest tests in a Phaser-CE project? Any help or guidance would be greatly appreciated.

 ReferenceError: PIXI is not defined

      1 | import 'pixi';
      2 | import 'p2';
    > 3 | import Phaser from 'phaser';
        | ^
      4 |
      5 | export function createGame() {
      6 |     const game = new Phaser.Game(800, 600, Phaser.AUTO, '', { preload, create, update });

      at Object.<anonymous> (node_modules/phaser-ce/build/custom/phaser-split.js:563:11)
      at Object.require (src/game.js:3:1)
      at Object.require (test/game.test.js:1:1)

What I've Tried:


Solution

  • Well I tried your code-example, and infact it doesn't run. So looked at it, and got it to run with small adjustments (I just looked at the jest part):

    1. installed a virtual canvas so, that phaser can "render":

        npm i --save-dev jest-canvas-mock
      
    2. removed the phaser, pixi and p2 imports from the index.js file.

    3. In the game.js changed the imports to:

       global.PIXI = require('PIXI');
       global.p2 = require('p2');
       global.Phaser = require('Phaser');
      
    4. altered the jest.config.js file to match the "imports":

       module.exports = {
           moduleNameMapper: {
               'PIXI': path.join(__dirname, '/node_modules/phaser-ce/build/custom/pixi.js'),
               'p2': path.join(__dirname, '/node_modules/phaser-ce/build/custom/p2.js'),
               'Phaser': path.join(__dirname, '/node_modules/phaser-ce/build/custom/phaser-split.js'),
           },
           //...
        }
      

    This should run your initial demo test (result seen in image below).
    (I hope the same change solve your issue.)
    Screenshot of running tests