James L.
James L.

Reputation: 14535

Creating library for Phaser.io with WebPack - Class extends value undefined is not a constructor or null

I am trying to write a small FOSS UI component library for the Phaser.io game engine. The code lives here. In the src/ dir I have a bunch of components that are exported in the index.js file. These components are bundled using the webpack.config.js and exported to build/phaser-ui.js.

I am having trouble using my built file. Inside the test/ directory, I have created a Phaser Game for testing with the phaser-plus Yeoman generator. My phaser-ui package is installed in the test's package.json from a relative link. This seems to work fine.

The issue I am having is that it appears my phaser-ui file does not have access to the Phaser Library. In the test game I am trying to import a component from the phaser-ui package.json dependency, but this causes the following error to be thrown.

Inside the Game.js state:

import ProgressBar from "phaser-ui";

stack trace error enter image description here

HTML5 Game Dev Forums post here Source repo here

Upvotes: 0

Views: 827

Answers (2)

James L.
James L.

Reputation: 14535

K so I got it halfway working (update - works 100%). I changed my test script to properly reinstall the package in the test dir each time: 

PHASER-UI's package.json

"scripts": {
 "test": "npm run build && cd test && npm install phaser-ui && npm start",
 "build": "webpack"
},

The test package installs phaser-ui from a local NPM directory

TEST's package.json

"dependencies": {
    "phaser-ce": "^2.7.0",
    "phaser-ui": "file:../"
  },

Then, I included the 'Phaser' variable as an external in my webpack

var webpack = require('webpack');

module.exports = {
    entry: './src/index.js',
    output: {
        path: 'build/',
        filename: 'phaser-ui.js'
    },
    //needed in my src library when extending/using Phaser objects/code
    externals: {
        Phaser: 'Phaser'
    }
};

So now it builds successfully and seems to work. The issue is that I don't know how to consume it in my game state. Importing and logging it only shows a generic object in the console

import * as lib from 'phaser-ui';

export default class Game extends Phaser.State {

  create() {
    console.log(lib)
  }

}

phaser-ui import

Update

Turns out I needed to add some library configuration to my webpack.config.js. By default webpack libraries are designed to be "installed" via a scripts tag and consumed via a global variable. I want my library to be a node_module that is consumed by an import componentName from 'phaser-ui';, so I needed to change the libraryTarget to umd.

Final webpack.config.js:

module.exports = {
    entry: './src/index.js',
    //setup the webpack output as a library
    output: {
        path: 'build/',
        filename: 'phaser-ui.js',
        libraryTarget: 'umd', //Honestly not sure of diffs between umd, amd, commonjs, etc (but umd works!)
        library: 'phaserUi'
    },        
    //needed in my src library when extending/using Phaser objects/code
    externals: {
        Phaser: 'Phaser'
    }
};

Upvotes: 1

vickson
vickson

Reputation: 73

In you code, you have, from line 1:

/*
 * Star
 * ====
 *
 * Individual star paritcles in the background star emitters
 */

export default class Star extends Phaser.Particle {
// ...

Looks like you haven't imported the library. Phaser is undefined, and so Phaser.Particle is undefined.

Did you forget to const Phaser = require('phaser'); before using Phaser?

Alternatively, you can do import {default as Phaser} from 'phaser'; If you want new syntax, and has set up environment to use it.

Upvotes: 1

Related Questions