Phaser: require('phaser') with Browserify throws error: Error: Cannot find module './Scalar'

Created on 11 Sep 2014  ·  115Comments  ·  Source: photonstorm/phaser

I've also got these errors:

  • Error: Cannot find module './Scalar'
  • Error: Cannot find module './Line'

Most helpful comment

There isn't a single module in Phaser, and never has been. It would require re-coding the entire thing from scratch, every single class, every single file. This is not something to be undertaken lightly, and I'm dubious of the merit of doing it at all, seeing as that's how Lazer is being built.

All 115 comments

Can you test something for me please - see if the build of Phaser that _doesn't_ include P2 errors as well? You'll find it in the build/custom folder.

I gave this a run with both phaser-no-physics.js and phaser-no-libs.js. While I no longer got the "Scalar" error, I now

Cannot find module 'nw.gui'...

Looks like a limitation of browserify. It seems to be addressed here:

https://github.com/substack/node-browserify/issues/653

What I currently do is atomatically copy phaser.min.js to my game folder using a grunt task.
And then use a browserify shim to point 'Phaser' to that file. It will work then and browserify won't complain. But it's a workaround.

A possible solution for the nw.gui test would be to try: require.resolve('nw.gui'); and catch the error as it is done now. That could fix the problem. Resolve only checks the path for the module and returns it if the module is available but doesn't load the module, and thus browserify won't have to load it.

I don't use browserify, so if anyone wants to try this fix out and see if it works, then I'll happily merge it if it does.

the require.resolve('nw.gui') works. And it builds fine with browserify. But without referencing the minified file it will complain PIXI is not found when it overrides the interactionmanager.

I'm trying to include phaser in my project with browserify as well, but I'm confused to say the least. Did this ever work? Why doesn't it work anymore? (I can see some module.exports stuff in the phaser src). Is the only way to include phaser right now by manually including it into the global scope?

I'm sure there are several workarounds that could be done with effort that could be more wisely spent working on the actual fix.

If you're purpose is just to get going, then global is your best bet. To make it work seamlessly when I or anyone else get the time to fix this, I'm also including another proxy file named "phaser.js" containing this:

// TODO find fix for this hack
module.exports = window.Phaser;

That way, I can still do var Phaser = require('phaser'); in my code. Whenever the fix comes around, I'll just remove the script tag and the matching hack file.

Ok thanks that sounds like a good solution for now.

I use a copy, command in my Gruntfile.js that copies the phaser lib to my game lib:

    copy: {
      phaser: {
       files: [
         { expand: false, flatten: true, src: ['node_modules/phaser/dist/phaser-arcade-physics.min.js'], dest: 'src/client/game/phaser-arcade-physics.min.js' }
      ]
      },
}

And then in my package.json:

  "browser": {
    "Phaser": "./src/client/game/phaser-arcade-physics.min.js"
  },
  "browserify-shim": {
    "Phaser": {
      "exports": "Phaser"
    }
  }

After that

var Phaser = require('Phaser');

then works fine, but it's a hack :)

Just started trying to use Phaser and have run into this bug. Is there perhaps an early version of Phaser I could use that doesn't have this issue?

The solution from @woutercommandeur is working for me. The only modification is using bower and avoid moving the file. I just point to the bower_components directory

"browser": {
    "phaser": "./bower_components/phaser/build/custom/phaser-arcade-physics.js"
},

PD: Sorry for my English

Cheers, but this still doesn't work - I'm getting an error "Cannot find module 'nw.gui'". I'd try that require.resolve thing mentioned above, but I've no idea where to put that :-/

@Rainbowlemon You need to reference the .min.js file and make sure it is copied to your project folder (and referenced from there). Otherwise you will get the nw.gui error or other errors.

webpack seems to have issues bundling Phaser too, given the errors it's probably related.

phaser
phaser2

Can confirm, want to use browserify and Phaser but seems like it's tough luck?

Edit:

Workaround I've found

browserify: {
    libs: {
        options: {
            exclude: ['nw.gui']
        },
        files: {
            'static/js/main.js': ['./src/client/**/*.js']
        }
    }
}

Followup on my last comment which I know may be offtopic and warrant another issue to be created. Seems that the way the phaser libs are built collide with webpack. I managed to workaround this using the script loader. Not ideal, but works for now.

    resolve: {
        alias: {
            "phaser": path.join(__dirname, "node_modules/phaser/dist/phaser-arcade-physics.js"),
            "phaser-debug": path.join(__dirname, "node_modules/phaser-debug/dist/phaser-debug.js")
        },
    },
    module: {
        loaders: [
            { test: /(phaser-arcade-physics|phaser-debug)\.js$/i, loader: 'script' },
        ]
    },

Full sample config
Hope this helps anyone facing this problem

What's webpack?

Man the list of package managers or build tools is crazy.

@photonstorm I linked it above. It kinda replaces grunt/gulp, browserify and some other tools (and that's an understatement). webpack sorry for derailing this conversation, the error seemed related.

Oh hell, _another_ one?! It's times like this I wish all package managers would just die out leaving one dominant one left.

Experimenting with browserify, I discovered that the arcade version 2.0.6 works well, in this boilerplate project via @lukewilde it browserifies correctly and I got that to work in a related project. https://github.com/lukewilde/phaser-js-boilerplate/blob/master/src/js/lib/phaser.arcade.js
When I used the default build from here: v2.1.3 "Ravinda" - Built: Thu Oct 23 2014 16:02:23 https://raw.githubusercontent.com/photonstorm/phaser/master/build/phaser.js
Then I encountered horrible puzzling errors in FFox/Chrome: Error: Cannot find module '__browserify_process'

Traces in Chrome:
Uncaught Error: Cannot find module '__browserify_process' _prelude.js:1s _prelude.js:1(anonymous function) _prelude.js:1../package.json phaser.js:75021s phaser.js:64969e phaser.js:64969(anonymous function) phaser.js:64969a phaser.js:64969browserifyShim phaser.js:64969(anonymous function) phaser.js:83583JkpR2F phaser.js:83585s _prelude.js:1(anonymous function) _prelude.js:1./properties app.js:1s _prelude.js:1e _prelude.js:1(anonymous function)

If I were to guess, the P2 stuff found below lines 62000 has a different looking module export statement at the front of it than the ones for Pixi and Phaser. Since the Pixi & Phaser in 2.0.6 arcade build are working ok, perhaps matching P2's export statement to them would work.

I think my error may have come via 66866, or a similar statement. Maybe the require statements on __browserify_process are somehow malformed to what browserify is expecting:

},{}],3:[function(require,module,exports){ var process=require("__browserify_process"),global=typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},Buffer=require("__browserify_Buffer"),__filename="/..\\node_modules\\poly-decomp\\src\\Line.js",__dirname="/..\\node_modules\\poly-decomp\\src";var Scalar = require('./Scalar');

Well, lets hope for the best in new release I guess

@photonstorm Sorry for off-topic, but webpack is browserify-compatible and it allows much more than browserify: different module styles, async loading and livereload even in production out of the box, semi-automatic code splitting into chunks that load separately, many loaders for different web resources (you can require an image or a stylesheet) and more. Please take a look at it, it is very promising and works well.

@sompylasar sorry for off topic again! Browserify + webpack is new to me.

What I am thinking here, is that these tools are superfluous? Just on the grounds that Phaser works as expected. This ticket is saying that the resource managers being used are not compatible with Phaser or vice versa. (But close your eyes and throw a dart at any JS lib, it cannot just be phaser with these issues?).

It seems any problem which these tools claim to solve are just creating more problems, and soon there will be "AnotherXName" project which claims to be better solving these problems... Just like the Browserify > WebPack stuff above has done. Then after that.... another one will come along claiming to solve it.

What is wrong with just standard JS when it comes to something as important as structure?

It's all down to preference, browserify allows me to use node modules easily and still generate one minified, uglified game.js file. I needed something to triangulate polygons and found a decent module on npmjs.org. npm install the lib. require in my code, and go.

Anyway, the solution from my comment above works fine, and it's what I'll be using.

What is wrong with just standard JS when it comes to something as important as structure?

The only standard JS that tries to solve the dependency management problem is ES6 Modules which is not widely supported yet. Why not use a tool that helps to manage the structure and re-use thousands of existing modules now in a compatible and widely supported way?

Before webpack, browserify was the only tool that allowed to re-use node modules in the browser. It has several flaws which webpack gently resolves.

The cause of this issue with Phaser is that its distribution file is a concatenation of several parts, each bundled for the browser separately with its own way of internal dependency management. When this file runs directly in the browser, it works because all the parts export their entry points as different global variables. When this file is used as a CommonJS module (which is a primary method for browserify and webpack), it fails because the UMD snippets included into each part fall into providing entry points via module.exports which is the same for the whole file, so only the last assigned entry point wins. Moreover, several parts of Phaser use global variables without requiring them - this fails because in CommonJS mode of UMD the assignment to the global variables is skipped.

I have just worked out a solution for webpack. Although it slightly patches the current Phaser distribution to fix inconsistent internal dependency management, it does this transparently during the build process without modifying the original sources.

For those who knows how to provide loaders for webpack:

    module: {
        loaders: [
            { test: /\/phaser\.js$/i, loader: "phaser-webpack-loader" },
            { test: /\/phaser-debug\.js$/i, loader: "phaser-debug-webpack-loader" },
            // ...
        ]
    },
    resolveLoader: {
        alias: {
            "phaser-webpack-loader": path.join(__dirname, "tools/phaser-webpack-loader"),
            "phaser-debug-webpack-loader": path.join(__dirname, "tools/phaser-debug-webpack-loader")
        }
    },
    resolve: {
        alias: {
            "phaser": path.join(__dirname, "node_modules/phaser/dist/phaser.js"),
            "phaser-debug": path.join(__dirname, "node_modules/phaser-debug/dist/phaser-debug.js"),
            // ...
        },
        // ...
    },
/** phaser-webpack-loader */
module.exports = function(source) {
    this.cacheable && this.cacheable();

    // Fix for `p2`, it replaces `Phaser` with itself in `module.exports` when in the same file.
    source = source.replace(/"object"==typeof exports/, 'false');

    // Fix for `Phaser` to depend on `PIXI` exported before in the same file.
    source = source.replace(/(var\s+\w+\s*=\s*)Phaser(\s*\|\|\s*\{)/, 'var PIXI = exports.PIXI; $1Phaser$2');

    // Do not replace `module.exports` object, only put a property on `exports`.
    source = source.replace(/typeof module !== 'undefined' && module\.exports/g, "false /* typeof module !== 'undefined' && module.exports */");

    // Fix for Phaser node-webkit detection.
    source = source.replace(/require\('nw\.gui'\)/g, "undefined /* require('nw.gui') */");

    // Fix for missing `require` for `p2`.
    source = source.replace(/(p2\.Body\.prototype)/, 'var Phaser = require("Phaser").Phaser; var p2 = require("p2"); $1');

    // Fix for direct reference to global `document`. Works without this patch, too.
    source = 'var document = global.document;\n\n' + source;

    return source;
};
/** phaser-debug-webpack-loader */
module.exports = function(source) {
    this.cacheable && this.cacheable();

    // Inject Phaser object via webpack's `require` from the outside of the `phaser-debug` module function which has got its own `require`.
    source = source.replace(/(var\s+ui\s*=\s*require\('\.\/util\/ui'\))/, 'var Phaser = _Phaser; $1');
    source = '(function () { var _Phaser = require("phaser").Phaser;\n\n' + source + '\n\n}());';

    return source;
};

The whole project I'm working on is a boilerplate that includes automatic index.html generation and a configured webpack-dev-server via a gulp task. I'm planning to add basic game structure and workarounds for CocoonJS. It won't fit into a single comment, so if someone needs it at its current stage, please tell me, I'll try to publish the repo asap.

Thanks for the clear explanation @sompylasar

+1 for the webpack

The way I'm managing this issue is not as clean as I would like but it works for all versions of Phaser.

I created a template (https://github.com/OttoRobba/browserify-phaser) which uses Phaser from npm.
The index.html is like this:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" content="content">
        <title>Phaser Game</title>
    </head>
    <body>
        <script src="./node_modules/phaser/build/phaser.js" charset="utf-8"></script>
        <script src="bundle.js"></script>
    </body>
    </html>

Bundle.js is made from calling Beefy, using game.js as the entry file, which is like this:

    //We use window.game because we want it to be accessible from everywhere
    window.game = new Phaser.Game(800, 600, Phaser.AUTO);

    game.globals = { //Add variables here that you want to access globally
    };

    game.state.add('play', require('./states/play.js'));
    game.state.add('load', require('./states/load.js'));
    game.state.add('menu', require('./states/menu.js'));
    game.state.add('boot', require('./states/boot.js'));
    game.state.start('boot');

This works fine and is probably the easiest workaround for now. I'd love to be able to properly require('Phaser'); in the future though.

It looks like this come from browserify creating CommonJS shims in libs & phaser build stuff concatenating it's products.

I notice p2js stuff in bundle/phaser.js

This isn't the only dep that uses browserify, but it might make sense to make the package.js main property something without the physics & add usage instructions to include these separately if using CommonJS (webpack or browserify.)

If I set the package.json main to ./build/custom/phaser-no-libs.js I get past the initial error, but then get another error like this:

Error: Cannot find module 'nw.gui' from 'node_modules/phaser/build/custom'

Which is probably related (because require is defined before shimming, and it's not requirejs, browserify thinks it might be node-webkit, which has other funny issues that have to be worked around.)

I think maybe the best solution is to switch over to CommonJS, or another module system (ES6 is an emerging standard & there are transpilers for it to convert to ES5) and build stuff that way, or don't concat and shim everything & use with browserify overrides (in the user's project.) Both would require changes to how the build-system works.

@konsumer You are right, the proposed solution may help, but you'll have to shim at least PIXI which Phaser depends on implicitly (see line 122 of https://raw.githubusercontent.com/photonstorm/phaser/master/build/custom/phaser-no-libs.js ).

nw.gui is another error that is caused by how Phaser detects Node-WebKit environment.
https://github.com/photonstorm/phaser/blob/d8fee414b8c0efe405860eaa5ebfab19d4026d5c/src/system/Device.js#L841 This one should be easily fixed by providing a browserify shim for this nw.gui module that resolves to undefined.

Anyways, Phaser should rework its dependency management and build process to support CommonJS the right way.

yep, you can add pixi to dependencies, and do var PIXI = require('pixi');

I am working on a light fork over here: https://github.com/notnullgames/phaser

We have it pretty close, but I am noticing some fancy stuff in system/Device.js that will need some attention.

Anyways, Phaser should rework its dependency management and build process to support CommonJS the right way.

This isn't going to happen, sorry. If someone wants to submit a PR that is proven to fix it, and doesn't mess anything else up, then I'll happily merge it, but that's all.

Yep, no prob. I am working on it in a fork, and am happy to submit a PR when it's all worked out, and also happy to just use my fork for my own specialized purposes.

@konsumer Please mention me in the pull request, I'd like to review it when it's ready.

I have a working branch with all the stuff I am not using moved out of the way. I am not sure I want to spend the time to convert all of phaser's build system on a "maybe that would be cool" but you can test mine with npm install notnullgames/phaser. I have a little demo project that uses it & browserify, here complete with beefy dev server & browserify.

With the included build commands, you can see an example of cross-platform building of a UMD library (it can be used in browser global, AMD, or CommonJS) https://github.com/notnullgames/phaser

Just run npm run full or npm run full-min. Once I figured out that the build/manifest files describe the load-order, it became very easy to make it work. The main trick is using modules.exports=Phaser in Phaser.js, var Phaser=require('../Phaser.js'); in all the other files, and adding the var PIXI=require('pixi.js') for everything that needs that. CommonJS uses the same object for every require after the first. Since these libraries are super-good about keeping everything in their namespace, it becomes very easy to deal with.

I'm tempted to create a version of Phaser.Device that contains _only_ the parts Phaser needs in order to run and strips out everything else. I imagine it'd be a tiny file actually.

I really love that idea.

Yeah, am working on it. Will do the same for some other classes too.

Sweet. Lemme know if I can help.

This feature request has been moved to the Phaser 3 feature list (so is being closed here)

@photonstorm Why a forum thread? It's not trackable... The feature requests would better be GitHub issues marked with a label and a milestone.

I don't want v3 clogging up the v2 repo (it has its own repo for that). I use the issues list as a bug tracker and it should be as close to zero as I can ever get it. I know some projects like to use it as a "todo" list as well, but I don't, sorry.

@nesukun hi! I was trying to use your workaround https://github.com/photonstorm/phaser/issues/1186#issuecomment-62481186 but when I am trying to reference phaser like this: require('phaser'); It returns empty object :/ Could you share working example please? Thanks

I have a working webpack example here: https://github.com/the-simian/phaser-webpack-output-example

@the-simian Funny I did similar loader but haven't published to GitHub yet.

@sompylasar I initially had not published it, but I decided to so I could go ahead and start keeping it handled with semver. I feel like its a bit kludgy- but it does allow a full use of webpack, in the way webpack was intended. Most of the browserify/webpack implementations I saw don't actually use npm for phaser, but keep a local module. I was trying to get away from that.

When I have time I am going to update the loaders to work with 2.3.x, as It does break right now (only works on 2.2.x).

This was the output of the slush-phaser-webpack scaffold I am using for my own purposes, but have opened for anyone to use. Its still under development, right now. I can see from this thread, the solutions are very similar (the find and replace stuff). I can see you wrote this much earlier than I did - Do you want to be listed as an author?

I feel like it slow, brittle work. I am reading that Version 3 will be common module compliant, and I hope that is true... In the meantime, it may have been more trouble than it was worth. Not sure.

@the-simian It's not rocket science actually, so I don't think listing me as author is necessary. But I really appreciate the suggestion!

Currently I've got no access to my repo, but I'll be glad to share what I've done (I don't remember if I made it compatible with 2.3.x, but I was targeting the latest release as of the time I did this).

@sompylasar Thanks for your input, thusfar!

In case you're curious, the slush scaffold I've been working on is here : https://github.com/the-simian/slush-phaser-webpack

If you, at any point get things working with 2.3.x before I do, we can just get it into the shim and both use it!

@the-simian Thanks for pointing to https://github.com/slushjs/slush , haven't heard about it before.

what is the point of the umd definitions in phaser if the thing only works reliably as a globally exported variable anyway?

phaser is broken in requirejs and browserify currently (v2.3.0) either p2 is undefined (requirejs) or cannot find module ../collisions/AABB/ or something similar with Browserify (even with the shim workaround)

@hayesmaker This shim workaround was for v 2.2.x. I had actually published a shim, and I deprecated it last night, since I got it working otherwise.

You can see a working version of this with the slush-phaser-webpack project. Just install that and scaffold fo a working example.

If you don't want to do that- here's what you _can_ do now

You can also include the correct build criteria yourself:

This can be achieved by simply including the dependencies that are necessary for Phaser to work:

global.PIXI = require('pixi.js');
global.p2 = require('p2');
global.Phaser = require('phaser')

You will need to use the correct versions of both pixi and p2. At the time of this writing, for [email protected] uses

{
  "phaser": "2.3.x",
  "pixi.js": "2.x.x"
  "p2": "0.6.x",
}

Also be aware that the npm module pixi is the _wrong module_, you want pixi.js, the official module

I also agree with you about the module being global. I occasionlly see that when dealing with certain modules expecting a global namespace. Angular, and jQuery for instance are like that. Its the whole reason for browserify-shim, and a lot of that sort of stuff. I am under the impression that Phaser is moving towards supporting amd. I suppose it would be ideal to have something like p2 = p2 || require('modules/p2)` or something similar to make it really work, if the code can't be seen globally. (You'll see a similar situation with pixi.js too).

For now, if you use my scaffold, or follow that tip above - it works.

Did phaser ever work with browserify?

It worked on my trimmed fork, and it sounds like maybe others got it working.

Definitely not out of the box. Various methods can be used as you can see in this very thread. But no official support for any of them, so work might need to be done when phaser is updated (that's why some of the solutions exposed here won't work anymore, including mine)

@hollowfork I got phaser working in webpack. If you look for slush-phaser-webpack, you can just generate a project. I'm still adding features, but it is stable

The basic strategy for me was to add require statements in everything for internal/external dependencies in each file, and monkey-patch the global-cached phaser object. I trimmed it because that sort of methodology obviates the need for all the concat/header/footer stuff. I could work on it again, without trimming so much. I just wanted a clean repo to use in other projects.

The easiest would probably be to concat everything from the src folder into a fresh module, but I don't know what order the dependencies are in. Also require checks would have to be transformed into require.resolve. I am wondering if support for envify https://github.com/hughsk/envify would be too much.

It's already half-concatenated half-browserified. The easiest is patching
via string replacement. The easiest is not the best. The best would be to
NOT concat everything, but split and make the sources work in a
CommonJS-only environment with NO global variables at all. Then make a
build script that glues the modules together for the browser (via
browserify or webpack) for someone who does not have a build step in their
apps.
30.05.2015 5:25 пользователь "hollowdoor" [email protected]
написал:

The easiest would probably be to concat everything from the src folder
into a fresh module, but I don't know what order the dependencies are in.


Reply to this email directly or view it on GitHub
https://github.com/photonstorm/phaser/issues/1186#issuecomment-106976408
.

@sompylasar I was doing as you described with the string replacement on the webpack-phaser-shim module (and I had also seen you do too).

I deprecated that with v 2.2.3; If you can stomach a couple modules being attached to global.Module, then it works really well with webpack now. I would assume browserify too, since they are similar in this respect. You might have to use the browserify shim modules; however, to make things work correctly.

Everything we did is a workaround for the incomplete CommonJS support. I
think this is what should be fixed, not worked around.
30.05.2015 20:03 пользователь "Jesse Harlin" [email protected]
написал:

@sompylasar https://github.com/sompylasar I was doing as you described
with the string replacement on the webpack-phaser-shim module (and I had
also seen you do too).

I deprecated that with v 2.2.3; If you can stomach a couple modules being
attached to global.Module, then it works really well with webpack now. I
would assume browserify too, since they are similar in this respect. You
might have to use the browserify shim modules; however, to make things work
correctly.


Reply to this email directly or view it on GitHub
https://github.com/photonstorm/phaser/issues/1186#issuecomment-107065384
.

@sompylasar I know what you're saying, but you're speaking of an ideal situation that is being solved in Phaser3. All I want now is an entry point that works. Concatenation with an umd at the end would achieve that best in my opinion. No need to re-engineer the whole thing. And globals don't make me worry all that much. As long as I know which ones are there they won't hurt my feelings.

I haven't found any browserified files in the src folder. The build has them, but I'm not sure where they come from.

It's totally doable with just browserify, and doesn't require re-engineering, just tracking of internal/external deps, properly. Please see https://github.com/notnullgames/phaser

@sompylasar , @hollowdoor ...sorry I was unclear.. I mean I am actually not using the shim anymore, as of v 2.2.3, it works with webpack. See full explanation here https://github.com/photonstorm/phaser/issues/1186#issuecomment-104306080

I was going to go make a fork and a PR, but they had already added the code in.

@konsumer interesting. I haven't tried yet, but can specific objects be loaded with your solution safely? Is it just a matter of looking at the errors to see which dependencies are missing? It looks like the ./Phaser file import is everywhere.

I did get it to browserify by the way. It's 787.7 kB minified FYI.

To tell you the truth I'd rather resolve system shims on my own so your version is fine.

Maybe you should publish a scoped phaser to npm. Unless you have, and the readme reads wrong.

I did try to install from the repo, but npm hanged on the install.

@konsumer
Oh freakin cool! I just did this with browserify, and babelify. It compiled just fine using your version of phaser.

import BitmapData from 'phaser';

export default class DebugLines extends BitmapData {
    constructor(game, grid, w, h){
        w = w || 800;
        h = h || 600;
        super(game, "debugLine",w, h);


        this.addToWorld(0, 0);
        this.ctx.strokeStyle = '#ff0000';
        this.ctx.lineWidth = 1;
        for(var i=40; i<w; i=i+40){
            this.ctx.beginPath();
            this.ctx.moveTo(i, 0);
            this.ctx.lineTo(i, h);
            this.ctx.stroke();

        }


        for(var j=40; j<h; j=j+40){
            this.ctx.beginPath();
            this.ctx.moveTo(0, j);
            this.ctx.lineTo(w, j);
            this.ctx.stroke();
        }
    }
}

Maybe I have been thinking about phaser modules the wrong way. I still have an glimmer of hope phaser2 gets better module support in this main branch though.

Looks like a spoke too soon because now I'm getting this error. TypeError: this.texture.baseTexture.dirty is not a function. I can't start an issue because this version of Phaser is not official. Maybe I'll try the forums, but I doubt it's a universal problem that will fit the official Phaser release.

I'm willing to put more work into the official version, especially if the official plan is to replace the concat/header/footer build stuff. Should I fork from dev maybe with a name like commonjs?

If I recall correctly, at least in phaser 2.x.x there is no intention to support broserify/webpack. I think I remember some forum thread in which @photonstorm stated that this kind of support wouldn't happen unless other did it, didn't mess with the way he works and didn't break anything.

Phaser 3 is another beast completely and modules support will probably (still nothing set in stone if I'm correct) come as a given as it "will be" (Again, nothing is set in stone AFAIK) written in ES6 / TS 2.0.

I love the work you guys are putting in enabling require-style modules support, but I don't know if its worth it, considering that no current projects could benefit of it as its not yet done 100%, it's a fork, therefore it will need to be synchronised with the original or will be obsolete, and maintenance burden will ever increase.

Again, thanks for the effort. Just leaving my thoughts here.

You will need to use the correct versions of both PIXI and p2. At the time of this writing, for [email protected] uses

@the-simian If I'm not mistaken, Phaser doesn't use the official PIXI builds OOB, the one included in Phaser is modified (I don't know to which extent). This could be outdated information.

Please accept my apologies if any of this information is incorrect, as I'm writing it based on what I recall.

@konsumer Do you want to add to this branch, or start your own? Are you talking about Phaser2, or 3? Just asking because what nesukun was talking about was confusing me. Perhaps he was speaking to someone else.

Now if the objective is to get the commonjs version into this dev branch I think it can be done if the requires, and exports you have in https://github.com/notnullgames/phaser were somehow templated into the js files using the Gruntfile then that would be a non-breaking solution that would probably work as long as the dependencies line up, and require('phaser') worked as if there was nothing changed at all. I would use this specialty build being the current commonjs doesn't work anyway.

I don't know if I'll contribute, but I am looking at the Phaser source. :)

@nesukun Maybe that's why I got an error about baseTexture.dirty not being a function.

@nesukun actually I didn't know that, I hadn't gotten any errors yet!

I looked in the source code to match version numbers, and that's where I came up with that particular package. If what you're saying is true I'll need to modify the build.

@hollowdoor I read your issue above. Hadn't run into that yet myself. Post here if you learn more precisely what is up. I'll need to fix my build. Looks like I'll be dipping into the node_modules and grabbing Phaser's "doctored" PIXI files... :(

I will add though, that I _did_ get errors when I did not use the right version number. The version of PIXI in Phaser is way, way behind. Makes sure of that, just to be on the safe side.

I'm just talking about whatever is in master/dev which according to the package.json in both is 2.X.X. Is 3 somewhere else?

I disagree about hacky templating and grunt to build it. It's not needed at all. A single browserify command can assemble it for everyone without a template, once all the deps are tracked correctly (as in my fork.) The result can be stored in git, if you really need that, but I'd recommend ignoring built files, and just build when needed for CDN/release.

@konsumer since v 2.3.x I'm not using the hack/shim anymore either,as I mentioned. There is a gulp task, but it simply calls webpack.

@konsumer 3 is somewhere else. About grunt maybe. I was just thinking of pushing back to this main fork, but not changing tons of files by hand. Just to get those requires, and exports like what you have without changing the the files in src. Then let browserify do it's thing just like what can be done with your fork. That way there's only the build script to maintain. I guess templates aren't hacky to me. I've been wrong before. Browserify is kind of hacky by the way. ;)

@the-simian It still doesn't work for me for some reason. You say you're using webpack, or browserify?

@hollowdoor - webpack, but they should respond similarly. what's breaking? you can give the slush-phaser-webpack a shot, I've been working on that when I can. Might try swapping out webpack with browserify and see what happens

npm install -g slush-phaser-webpack
mkdir browserify-example-slush-phaser
cd browserify-example-slush-phaser
slush phaser-webpack

Then after that, swap out webpack with browserify, see what happens. Id' expect it to basically work.

Cool, my main point was working CommonJS obviates the need for templates/header/footer/etc. With a CommonJS system, people are free to use whatever build system they like in their own project (webpack, browserify, etc.) If @photonstorm wants to use webpack or any other CommonJS tool for this project's builds (for CDN and release) that really doesn't affect me, as long as the CommonJS is functional. I can pick and choose the files I want in my own project's build.

@hollowdoor the requires & exports need to be in the files in src otherwise it's a mega-hack, in my opinion. I disagree that browserify is hacky. It does 1 thing, really well: build a pile of CommonJS files that are properly formatted into a js file. WIthout templates, using different entry-point files, you can make a million permutations of this project (selecting different physics engines, no physics, leave out whatever you don't need, etc.) This is not possible if a build-step using templates is required. I'm not advocating for browserify anyway, it's just what I use personally in my projects that will depend on phaser, but users can use anything that works with CommonJS (there are a lot of tools for this.)

@nesukun ah, cool. thanks!

@konsumer Hm. If you're saying remake Phaser in CommonJs', and just browserify/webpack compile a stand alone Phaser for regular script links, and leave it as modules for the rest of us that sounds good. I was concerned that would be too much of an overhaul for photonstorm, but if it works like usual that's not breaking. I would be all for that personally. I will test it if you want to go ahead with the dev branch. You've already got a proof of concept.

@the-simian I might give slush a look, but I'd still like to have some module consistency in the main fork.

@hollowdoor Should work the same, and if it'll get used, I'll even do the work. I'm not sure what yer issue is, but it may be upstream or I forgot a require somewhere.

@konsumer It's all good. I'll just watch what you're doing. Large projects can wait for modules. I have several that have gotten out of hand, and modules would help quite a bit. Walls of code lines that make me blurry eyed. If I think I can help on the fork I'll lend a hand.

I think my issue is a missing PIXI method. It's might be in BitmapData. I'll go there if you want me to start an issue.

@hollowdoor try to require the PIXI that is located in the node_modules of Phaser.

I might give slush a look, but I'd still like to have some module consistency in the main fork.

Slush is just a thing that kicks off gulp processes. I has nothing to do (or not to do) with module consistency. I actually have no idea what you mean by this sentence. The included version of phaser in that generator is based on the main fork, straight off of npm. I am suggesting using it, because you can go from a working build (webpack) to a working build (browserify) without spending too much more time stumbling in the dark. They should treat the modules the same, as I said- but you might need to include browserify-shim (just like if you were shimming angular or jQuery). Yes, it uses gulp, but gulp just callsbrowserify directly. I use gulp because I do a lot of _other_ stuff, like complexity analysis in the generator, and plan on adding even more.

I also agree with @konsumer that browserify is by _no_ means hacky. I use browserify at work (I actually architected our modern build system in that and gulp) and I use webpack in some personal projects. They're both very good, and the differences aren't so great that one is clearly superior to the other. They both build commonJs modules, and get the job done. Browserify might require the browserify-shim plugin in order to handle some global libs. I agree with @Konsumer that a full on CommonJs system for Phaser would be ideal, but thankfully in 2.3.x somone added the exports code at the base of the main file. Yes, its already built- but it does at least work with both browserify and webpack. It did not work in 2.2.x without some bad fixes. I have abandoned those shims, moving forward they aren't necessary. The current version does not break build, even if it is less than ideal.

@the-simian When I use 2.3.x it breaks with a ton of not found require errors. I've read the file with the exports code. I npm installed it, and it's still not compiling with browserify.

The module consistency I was talking about is what the main Phaser has, or doesn't have as the case may be. There are files with relative requires that aren't relative any more in the concatenated module of Phaser. I'm going to try again, but my last try was just a few days ago so I don't foresee any changes. Call it a personal preference, but I'd rather just have something that works. I already have several mostly completed projects. It would not be a problem to transfer those to modules.

The only thing I'm worried about is Rich has expressed dislike for browserify in the html5gamedevs forums. Also photonstorm doesn't want any code changes to mess up their work flow. Another build step for modules is something that would stall a work flow. That's why I was talking with @konsumer about templating the exports in because a global change to modules in the main source would require a build step for the main Phaser devs. They obviously don't want that. Even though I'm sold on CommonJs in Phaser not every one agrees it's the best way.

I'm of the opinion that Phaser was developed with a diverging dependency graph mind set like most older javascript libraries. Modules are a more convergent mindset so while modules can benefit any project in Phaser they would clash a little bit. Especially at the size of the current code base. That's just my opinion. :)

I think I just figured out how to fix it. I feel sort of stupid. There are really only two problems.

  1. The requires in the build/phaser.js are browserified versions of modules so they need to be derequired.
  2. The check for require('ng.gui') needs to be something else like others said require.resolve('ng.gui').

That would probably get Phaser 95% working with whatever commonjs bundlers there are.

Also I don't understand how PIXI, and p2 are undefined in build/phaser.js when Phaser is a module, and running the same as a script link still works.

BTW. I did derequire phaser.js, and replaced require('ng.gui') with require.resolve('ng.gui'), and it worked. :) I'm too lazy to start a fork.

The thing about these libs that use this old monolithic use-script-tags approach is that they are fairly easy to convert to CommonJS. Basically they all monkey-patch a primary namespace, and since CommonJS uses a single cached object for requires, you just need the requires at the top. Very easy.

@konsumer Though what you said is true I'm not sure what you're getting at.

BTW there is a pixi.js file in the phaser/dist/modules folder that will fix this error TypeError: this.texture.baseTexture.dirty is not a function if you put that in your fork at https://github.com/notnullgames/phaser instead of var PIXI = require('pixi.js');. I believe dist is created by the grunt file as a prepublish so you have to get phaser/dist/modules/pixi.js from Phaser on npm. Unless you want to put module.exports in all those pixi files in src that is, or run that grunt file manually to get pixi out of it.

@konsumer Oh now I understand. Yeah. I was thinking in terms of the set up that photonstorm has right now. The clash is really a mind set. I had to pick up the pieces of my brain after trying to understand modules back in the day when I was studying python. Now that I do understand them I can't get enough of them. They're almost too easy. I'd like to see them work right in Phaser. Hopefully Phaser3 will do it right. Not that I don't appreciate the work every one is doing on Phaser, and how awesome it is as a game framework.

Just to say that I'm preparing 2.4 for release, so if anyone reading this wants or needs to get more changes in to make your module life easier, now is the time to submit PRs. I merged in one tonight that fixed the require issue with NW.

Also just to add that Phaser doesn't use _any_ official release of Pixi any longer. We have diverged too far from the v2 codebase with our own fixes and updates. So if you're doing anything that is requiring Pixi from npm you'll need to change that.

Is the version use photonstorm/pixi.js? If so, maybe this should be tracked in package.json. You can track it like this:

{
  "dependencies": {
    "pixi.js": "git://github.com/photonstorm/pixi.js"
  }
}

I wonder if that project doesn't have it's own CommonJS issues, though.

No it doesn't use that fork any longer. It's a custom version specifically for Phaser, and is part of the core code base. I guess technically I could move it out to its own repo, but it's utterly useless on its own so I'm not sure it's worth the effort.

@photonstorm It's more important to make pixi.js a CommonJS-compatible module, and make the rest of the codebase depend on it. Avoid resolving it via global variables, use require. You could then either use relative path require or use it as an npm local path dependency and require by module name.

I'm afraid I'm not willing to spend any time doing that. It would require rewriting a good chunk of Pixi v2, which isn't a sensible use of my time.

I wonder if just adding a reference to PIXI in the exported Phaser. That way, CJS users can do 'var PIXI = require("phaser").PIXI;' and grab the reference without using globals or having to heavily modify the way Phaser is built.

Sounds better to me. If someone wants to go ahead and submit a PR that gets it working I'll happily merge. I reckon I've another couple days of testing and fixing before 2.4 is final.

@photonstorm Did some one put the PIXI reference in? Seems strange that there would be a reference to a global dependency in the dependent.

Updates?

tried this recently with Phaser 2.4.4 and browserify still shits itself on PIXI. If I have time over the holiday season I hope to address this and send a PR as an Xmas present to the Phaser community =)

Is anyone here can make a TL;DR on how to make it work with browserify. I read from the beginning but everything seems to be hacky. I saw instructions in the README for Webpack but doesn't help much for browserify. I already have a pretty huge stack built with browserify so i don't want to change my build system for the moment. The error i'm getting is:

phaser.js:23083 Uncaught ReferenceError: PIXI is not defined

If someone explain it right, I'll make a PR to add to the README so that no-one will have to ask on this post anymore

It's looking for pixi to be defined globally. The proper way to fix this is to define the requirement, at the top of any file that references PIXI:

var PIXI = require('pixi.js');

The quick hack way is to monkey-patch it into the window, before you require phaser:

window.PIXI = require('pixi.js');

You will probably still need to monkey-patch all the phaser stuff into the global Phaser object. You can see an example, here where I actually track all the external & internal dependencies on a per-file basis.

I wish i made it to work with browserify-shiw but i just can't seem to find anything that works at all. I'll stick with the monkey-patch for now as i don't want to lost time with Phaser's wrong UMD definitions. I really love this framework but I find it so sad that the foundation of the framework, the dependency resolution is done so wrong. It could be easier for everyone to build their custom version of Phaser if every module was declared in UMD with proper resolution of dependencies. The best exemple I have for that is lodash. You just require the files you want in your build and that's it, no need for cloning and custom grunt task, it works with CommonJS/AMD/Window like a charm. I really want this to be in the v4.

There isn't a single module in Phaser, and never has been. It would require re-coding the entire thing from scratch, every single class, every single file. This is not something to be undertaken lightly, and I'm dubious of the merit of doing it at all, seeing as that's how Lazer is being built.

@D34THWINGS I've gone back and forth on this for a long time and have dug into many threads on the topic. In short, @photonstorm has given the best answer available. As I understand it, the Phaser team has made so many modifications to their own custom fork of PIXI that it's essentially a different package at this point, and there is no browserify magick that will make the npm version of those two packages work together.

You can still use Phaser as an npm package, but just do it like this:

  1. Install Phaser as an npm package: npm install --save phaser
  2. from your project root, create a /static/vendor folder and add a symlink to your node_module:
    phaser -> ../../node_modules/phaser
  3. In your index.html just inject Phaser into the global scope by pointing to the symlink:
  <body style="margin: 0; padding: 0;">
    <!-- Have to include Phaser via script tag due to an incompatibility with Browserify -->
    <script type="text/javascript" src="/static/vendor/phaser/dist/phaser.min.js" defer></script>

    <script type="text/javascript" src="static/dist/bundle.js" defer></script>
  </body>

Then you can just refer to the Phaser object anywhere in your application, and the browser will recognize it since it's part of the global scope. But since it's still just a package, you can avoid adding the source to your repo etc.

Granted this approach is not aesthetically perfect, but speaking from experience it's a much better use of your time to simply punt on this issue for now and focus on building your game.

@galarant i'd better stick with the window hack for now because if i include it in my index.html, i will have to do a custom task to copy Phaser somewhere in my build from the node_modules then modify the name file for cache busting purpose if phaser is updated and also replace the relative path to the file to an absolute path to my Akamai CDN like I do with every single assets i have, and that's kind of work i can't afford for now. As you said, i need to focus on making the game, thanks for the advices !

Thanks @photonstorm for your work and sorry for bringing back old issues from the dead. I did a lot of development in Node and built huge frontend webapps but never seen libraries without proper UMD, that's why it surprised me, but I understand that it's not top priority. The JavaScript scene has a huge churn and tools come and go really fast, that's truly annoying.

@photonstorm I did manage to do the modular thing in my fork with (which is 1486 commits behind photonstorm:master,) and it does work. I traced the concat-order you are using in your build system, turned those into requires, and defined PIXI & Phasor wherever it was needed (at the top of many files.) A similar idea could be applied to this repo, but I couldn't figure out what version to apply the changes to, and it sounded like it would duplicate other efforts you have going on.

You can test it out by downloading it, running npm install and npm run full-min which will build phaser.js & phaser.min.js

hah looks like @konsumer actually achieved the task I wanted to do four months ago but gave up on. Awesome work!!

Thanks! It's outdated, but fairly easy to redo. Basically put these at the top of every file:

var PIXI = require('pixi.js'); // npm install --save pixi.js
var Phasor = require('../Phasor.js'); // whatever the location is relative to the file you are in

and then make a commonjs entry-point like mine. I based that on the current build stuff to figure out the right order. You can make multiple entry points for all the different versions of built files you want, but also, you can just include the files directly in your browserify/webpack project.

It relies on the trick that commonjs keeps a singleton reference to the object in module.exports, so anywhere that you include Phasor.js, you are getting the same object (so you can monkey-patch new stuff into it)

just add a script tag to ur html to add Phaser. It saves you having to
recompile 100,000lines of phaser code each time you browserify. And it
works.

On Tuesday, 12 April 2016, Benjamin Delamarre [email protected]
wrote:

Is anyone here can make a TL;DR on how to make it work with browserify. I
read from the beginning but everything seems to be hacky. I saw
instructions in the README for Webpack but doesn't help much for
browserify. I already have a pretty huge stack built with browserify so i
don't want to change my build system for the moment. The error i'm getting
is:

phaser.js:23083 Uncaught ReferenceError: PIXI is not defined

If someone explain it right, I'll make a PR to add to the README so that
no-one will have to ask on this post anymore


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
https://github.com/photonstorm/phaser/issues/1186#issuecomment-209094292

@hayesmaker I don't recompile Phaser each time since I marked it as external in my build. I have a second build for my vendors that I run only once at the start of my dev task and it works like a charm. That's how i do my dev build :

return browserify(options)
    .transform('babelify')
    .external(vendors);

And for my vendors build :

return browserify()
    .require(vendors);

@konsumer when I was reading the thread i saw your fork and it was a great job but as you said it's outdated. And @photonstorm said that you shouldn't use the pixi.js repo since Phaser has a very custom version of PIXI, so the require of PIXI should also be relative. I think that the best way to achieve this is to fix the UMD. I'll try to make a POC this weekend on a fork. I think it could be more trivial than we think.

Here's an example, thats how Phaser uses UMD at the moment:

(function (root) {
    var Phaser = {};
    // ... Phaser code goes here

    if (typeof exports !== 'undefined') {
        if (typeof module !== 'undefined' && module.exports) {
            exports = module.exports = Phaser;
        }
        exports.Phaser = Phaser;
    } else if (typeof define !== 'undefined' && define.amd) {
        define('Phaser', (function() { return root.Phaser = Phaser; })() );
    } else {
        root.Phaser = Phaser;
    }

    return Phaser;
}).call(this);

But the proper way to it is:

(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    define(['./pixi'], factory);
  } else if (typeof exports === 'object') {
    module.exports = factory(require('./pixi'));
  } else {
    root.Foo = factory(root.PIXI);
  }
}(this, function(PIXI) {
  var Phaser = {};
  // ... Phaser code goes here
  return Phaser;
}));

Using the factory pattern is way more efficient to handle dependencies for everything. And you don't have to do this on your own, there's some grunt and gulp plugins that can do that. You juste have to tell for each file what it depends on and everything will be wrapped up in the end so no pollution nor conflicts on the global scope can happen.

Also the UMD shouldn't wrap the whole code but each file so that each file can resolve dependencies on it's own. You will not have to change anything in the custom building feature since you'll have to concat all files in the right order because UMD wrapping doesn't solve the problem of defining order. The only thing that will change is the intro/outro that will no longer be required.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lilijreey picture lilijreey  ·  4Comments

rootasjey picture rootasjey  ·  3Comments

HDouss picture HDouss  ·  3Comments

samme picture samme  ·  3Comments

Secretmapper picture Secretmapper  ·  3Comments