New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
require('phaser') with Browserify throws error: Error: Cannot find module './Scalar' #1186
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 |
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
|
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. 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:
That way, I can still do |
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:
And then in my package.json:
After that
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 |
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 Traces in Chrome: 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:
|
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. |
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 |
Thanks for the clear explanation @sompylasar |
@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.
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 |
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 |
@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 {
"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 |
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:
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
The quick hack way is to monkey-patch it into the window, before you require phaser:
You will probably still need to monkey-patch all the phaser stuff into the global |
I wish i made it to work with |
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 You can still use
Then you can just refer to the 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 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 |
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:
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 On Tuesday, 12 April 2016, Benjamin Delamarre notifications@github.com
|
@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 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. |
I've also got these errors:
The text was updated successfully, but these errors were encountered: