Closed totty90 closed 9 years ago
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:
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.
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).
I've also got these errors: