proyecto26 / ion-phaser

A web component to use Phaser Framework with Angular, React, Vue, etc 🎮
https://market.ionicframework.com/plugins/ionphaser
MIT License
251 stars 39 forks source link

Next.js: ReferenceError: Phaser is not defined #36

Closed FilipeAleixo closed 3 years ago

FilipeAleixo commented 3 years ago

Tried running the React example directly in my Next.js app, but got the error "window undefined".

To try to solve this problem I loaded Phaser and ion-phaser dynamically, while disabling SSR (i.e., only importing in the client side) as follows, but now get:

index-53dab568.js:593 ReferenceError: Phaser is not defined at IonPhaser.initializeGame (ion-phaser.entry.js:19) at IonPhaser.connectedCallback (ion-phaser.entry.js:50) at safeCall (index-53dab568.js:233) at fireConnectedCallback (index-53dab568.js:436) at initializeComponent (index-53dab568.js:405) undefined

import dynamic from 'next/dynamic'

const Phaser = dynamic(
  () => import('phaser'),
  { loading: () => <p>Loading Phaser...</p>,
    ssr: false 
  }
)

const IonPhaser = dynamic(
  () => import('@ion-phaser/react').then((mod) => mod.IonPhaser),
  { 
    ssr: false 
  }
)

const App = () => {

  const state = {
    initialize: true,
    game: {
      width: "100%",
      height: "100%",
      type: Phaser.AUTO,
      scene: {
        init: function() {
          this.cameras.main.setBackgroundColor('#24252A')
        },
        create: function() {
          this.helloWorld = this.add.text(
            this.cameras.main.centerX, 
            this.cameras.main.centerY, 
            "Hello World", { 
              font: "40px Arial", 
              fill: "#ffffff" 
            }
          );
          this.helloWorld.setOrigin(0.5);
        },
        update: function() {
          this.helloWorld.angle += 1;
        }
      }
    }
  }

  return (
    <IonPhaser game={state.game} initialize={state.initialize} />
  )

}

export default App;
jdnichollsc commented 3 years ago

window undefined I don't have experience with NextJS, but about this first error, did you try creating that window global object? maybe using a polyfill 🤔

Something like this:

if (typeof window === 'undefined') {
    global.window = {}
}

Let me know 👍

FilipeAleixo commented 3 years ago

This worked:

import dynamic from 'next/dynamic'
import Phaser from 'phaser';

const IonPhaser = dynamic(
  () => import('@ion-phaser/react').then((mod) => mod.IonPhaser),
  { 
    ssr: false 
  }
)

const App = () => {

  const state = {
    initialize: true,
    game: {
      width: "100%",
      height: "100%",
      type: Phaser.AUTO,
      scene: {
        init: function() {
          this.cameras.main.setBackgroundColor('#24252A')
        },
        create: function() {
          this.helloWorld = this.add.text(
            this.cameras.main.centerX, 
            this.cameras.main.centerY, 
            "Hello World", { 
              font: "40px Arial", 
              fill: "#ffffff" 
            }
          );
          this.helloWorld.setOrigin(0.5);
        },
        update: function() {
          this.helloWorld.angle += 1;
        }
      }
    }
  }

  return (
    <IonPhaser game={state.game} initialize={state.initialize} />
  )

}

export default App;
jdnichollsc commented 3 years ago

Awesome, thanks for letting me know! ❤️