Closed mkristo closed 8 years ago
Yes the way it was previously bundled was completely wrong - PIXI should never have been inside the Phaser UMD, so it's now properly split out. The grunt custom
build task has a new flag --split true
which will generate Phaser, Pixi, P2 and Creature to their own stand-alone build files, each with the wrappers they need. So you can now bundle them together however you want. As long as they're allowed to exist globally they will be much happier. PIXI needs to come before Phaser in any requirement chain.
I understand now. Yes, this makes much more sense.
But when installing Phaser 2.4.2 via npm it seems like PIXI is still bundled with (at least) the no-physics build. I think it would be desirable to provide the split up modules as well.
Also, we should probably update the Webpack boilerplate to require both PIXI and Phaser. I'd be happy to do this, but the PIXI module needs to be available before this is done.
FYI, I can currently get Phaser to build by doing this:
global.PIXI = require('pixi.js');
global.p2 = require('p2');
global.Phaser = require('phaser');
In this case, PIXI is set to version
"pixi.js": "2.2.x",
I will add, though that this no longer works in 2.4.3. because the CanvasPool mixin is not defined on PIXI. If you require the CanvasPool file in between PIXI and Phaser, of course, it mixies in correctly, and works.
I'm aware that this involves setting some globals, which isn't ideal- but ti does allow you to use npm to serve all the modules.
I'm going to update my slush generator with these changes as soon as 2.4.3 is on master
Just to say that I've got a guide to setting up Phaser with Webpack which I'll publish shortly.
I'd just like to add one thing though: don't ever use any version of Pixi that you find in npm with Phaser, as it won't work. You have to use the version we've built specifically or so much will break.
p2 on the other hand should be safe to pull in from npm instead of the build included with Phaser as long as you use the exact same version that Phaser bundles with it, any deviation from that is highly likely to break it.
I noticed that the mixins you were using with PIXI were located in the utils directory. My question is, could we still use the npm version, as long as we mix in all the addons (like the CanvasPool). Are you actually changing the source code itself, currently - or are you modifying PIXI entirely by adding new properties?
If you're doing the latter, it could be possible to still use the npm PIXI and then just require a file you provide in the source that then mixes in all your modifications to PIXI. Of course, the same rules apply - you have to match the right version. I know PIXI is well into v3, but you are (last I checked) locking pixi on v 2.2.8. This could be useful because that way you'd really only have to maintain the parts that deviate from pixi.js source. So to be clear, I am imagining that you could require pixi with npm, and then require a file that basically requires all the addons in the right order, and just plug all the functionality you need right in. You would have the latitude to update or replace existing methods if you needed to. If I knew more specifically the parts that deviate from PIXI I would be happy submit a PR that basically works this way.
If I'm way off, and this wouldn't work in your opinion, I'd like to know more. Any amount you can elaborate on what's different about this PIXI from the core pixi (of the same version) I'd love to know.
In the meantime, is the most correct file to include from the Phaser source for PIXI currently
src/pixi/Pixi.js
right? You'd still need the CanvasPool and stuff like that afterwards, I would assume.
Thank you for taking time to respond to all these issues, I really appreciate the work you're putting in on Phaser!
The PIXI source in the Phaser repo is vastly different to the last published version of Pixi 2. We've added and fixed so much that isn't in the official repo it's not even close any more.
Here's how to use Phaser with Webpack:
1) You have to use a custom build of Phaser. You cannot use one of the builds from the dist folder. Here is the grunt custom task I used:
grunt custom --exclude p2,creature,ninja --split true
This will create phaser.js and pixi.js files in the dist folder. Copy those over to your project folder.
2) In Webpack you need to install the script-loader:
npm install script-loader --save-dev
3) In your webpack.config.js flag Phaser and Pixi to use the script loader. There are various ways of doing this, but I used this approach:
module.exports = {
entry: "./src/entry.js",
output: {
path: __dirname,
filename: "bundle.js"
},
module: {
loaders: [
{ test: /pixi.js/, loader: "script" },
{ test: /phaser.js/, loader: "script" }
]
}
};
4) In my entry.js I just have this:
require('../lib/pixi.js');
require('../lib/phaser.js');
require('./main.js');
main.js contains my test game, which is just a basic Phaser example.
5) Then build it.
Using the split Phaser / PIXI libs and the Webpack script loader I was able to bundle my game up quite happily without any changes to the core Phaser source.
Thank you for responding so quickly!
I will try this out as soon as possible
I'm getting the error Phaser.game is not a function,
Check you followed the instructions above exactly as written. If it still doesn't work post your project structure and conf file up.
Ok I got it now it works after cleaning my project folder. I didn't bother to check what script loader does..
I'm happy with the solution provided above.
@photonstorm: Should I close the issue, or do you want it to be open?
I'll leave it for now until I've moved the above instructions somewhere more public.
I had the same problem days ago. With Webpack + Bower. To be able to use commonJS-style i did this simple config
var webpackConfig = {
// ...
externals: {
"phaser": "Phaser"
}
// ...
};
and then
var phaser = require('phaser');
In my opnion. The bower should keep the main like that, but still export all submodules sources. To easly make custom builds from bower overrides.
Or like lodash, exporting allsubmodules in npm. E.g. : https://www.npmjs.com/package/lodash.shuffle
Currently, the only way to do custom build is from grunt
could we get a more full set of instructions for this in a public place?
I try to write a shim module for ES6 and webpack.. https://github.com/amowu/phaser-shim
Thanks, @amowu! It works!
@amowu nice. You guys also may like my phaserjs boilerplate. It's ES6+Gulp+Webpack
Phaser also are called by require(); And stats.js too.
@webcaetano đź‘Ť
@photonstorm using script-loader prevents minification because the module is loaded as a string and then evaluated (see https://github.com/webpack/script-loader/issues/1).
i used following webpack config to load pixi with imports-loader, then directly provided as PIXI
variable to phaser. files in lib/
are built using @photonstorm's method described above https://github.com/photonstorm/phaser/issues/1974#issuecomment-134222165. no probs with minification during build.
{
resolve: {
alias: {
"pixi": path.join(__dirname, "lib/pixi.js"),
"phaser": path.join(__dirname, "lib/phaser.js")
}
},
module: {
loaders: [
{test: /phaser\.js$/, include: path.join(__dirname, 'lib'), loader: 'imports?PIXI=pixi'},
]
}
}
no need to require pixi in my code files:
var Phaser = require("phaser");
// ES6
import Phaser from "phaser"
None of these are solutions, just leaking bandages. Phaser must evolve accordingly to maintain relevance in an ES6 world. If jQuery can do it, so can Phaser.
^^
Yes, the following should just work: npm install --save phaser
followed by import Phaser from "phaser"
. I've used many other libs this way, and anything else isn't good enough.
Thanks @dlindenkreuz, your solution worked perfectly for me.
None of these are solutions, just leaking bandages. Phaser must evolve accordingly to maintain relevance in an ES6 world. If jQuery can do it, so can Phaser.
That is what Lazer is for. I have no intention of ever making that change to Phaser, it's too close to end-of-life to be worth the effort.
Given 2.4.5 now has a webpack build option built in, and the README updated to reflect that I'm going to close this issue off now.
Taking @dlindenkreuz's approach a different direction—you can also expose the files from node_modules
in Phaser 2.4.5+ so you don't have to make a custom build and still get minification. Unfortunately all the files have to be global due to a circular reference (Phaser file pulls PIXI
global var, and pixi.js
references Phaser
from a function). The expose-loader works well here (I could not get the ProvidePlugin to work).
npm install --save phaser expose-loader
var path = require('path');
// Phaser webpack config
var phaserModule = path.join(__dirname, '/node_modules/phaser/');
var phaser = path.join(phaserModule, 'build/custom/phaser-split.js');
var pixi = path.join(phaserModule, 'build/custom/pixi.js');
var p2 = path.join(phaserModule, 'build/custom/p2.js');
module.exports = {
...
module: {
loaders: [
{ test: /pixi\.js/, loader: 'expose?PIXI' },
{ test: /phaser-split\.js$/, loader: 'expose?Phaser' },
{ test: /p2\.js/, loader: 'expose?p2' },
...
]
},
resolve: {
alias: {
'phaser': phaser,
'pixi': pixi,
'p2': p2,
}
}
};
Then in your entry file:
// commonjs
require('pixi');
require('p2');
require('phaser');
// or es2015
import 'pixi';
import 'p2';
import "phaser";
This is similar to making it an webpack external, but at least webpack can bundle it together and minify it now.
npm install --save phaser expose-loader
var path = require('path');
// Phaser webpack config
var phaserModule = path.join(__dirname, '/node_modules/phaser/');
var phaser = path.join(phaserModule, 'build/custom/phaser-split.js');
var pixi = path.join(phaserModule, 'build/custom/pixi.js');
var p2 = path.join(phaserModule, 'build/custom/p2.js');
module.exports = {
...
module: {
loaders: [
{ test: /pixi\.js/, loader: 'expose?PIXI' },
{ test: /phaser-split\.js$/, loader: 'expose?Phaser' },
{ test: /p2\.js/, loader: 'expose?p2' },
...
]
},
resolve: {
alias: {
'phaser': phaser,
'pixi': pixi,
'p2': p2,
}
}
};
// main.js
import 'pixi';
import 'p2';
import "phaser";
Hi there, it makes a alot of comment with author (look at http://imgur.com/a/WamqO mini map yellow comment), does any one know this problem ?
@supermrji these comment blocks contain @license
and are not removed by uglifyjs. you can pass a config object to webpack.optimize.UglifyJsPlugin
with comments: false
, this should remove all comments.
It would be nice, if phaser could be used without specific configuration for webpack. I often share a generic webpack configuration between multiple projects and it would ease development.
I use Phaser from npm and nom I would adding Box2D Plugin but I have many errors from "goog" and goog.global.CLOSURE_UNCOMPILED_DEFINES
var path = require('path')
var webpack = require('webpack')
var BrowserSyncPlugin = require('browser-sync-webpack-plugin')
// Phaser webpack config
var phaserModule = path.join(__dirname, '/node_modules/phaser/')
var phaser = path.join(phaserModule, 'build/custom/phaser-split.js')
var pixi = path.join(phaserModule, 'build/custom/pixi.js')
var p2 = path.join(phaserModule, 'build/custom/p2.js')
var box2D = path.join(__dirname, '/src/libs/box2d-plugin-full.js')
var definePlugin = new webpack.DefinePlugin({
__DEV__: JSON.stringify(JSON.parse(process.env.BUILD_DEV || 'true'))
})
module.exports = {
entry: {
app: [
'babel-polyfill',
path.resolve(__dirname, 'src/main.js')
]
},
devtool: 'source-map',
output: {
pathinfo: true,
path: path.resolve(__dirname, 'dist'),
publicPath: './dist/',
filename: 'bundle.js'
},
watch: true,
plugins: [
definePlugin,
new BrowserSyncPlugin({
host: process.env.IP || 'localhost',
port: process.env.PORT || 3000,
open: false,
server: {
baseDir: ['./', './build']
}
})
],
module: {
loaders: [
{ test: /\.js$/, loader: 'babel', include: path.join(__dirname, 'src') },
{ test: /pixi\.js/, loader: 'expose?PIXI' },
{ test: /phaser-split\.js$/, loader: 'expose?Phaser' },
{ test: /p2\.js/, loader: 'expose?p2' }
]
},
node: {
fs: 'empty'
},
resolve: {
alias: {
'phaser': phaser,
'pixi': pixi,
'p2': p2,
'box2D': box2D
}
}
}
Can you help me please?
test: box2d,
loader: 'imports?this=>window'
@photonstorm any plans on making phaser more native to ES6? I know you said that you're not planning on doing this, but I'm asking because it's often the case that plans change from year to year. This is a convenience I and the community would really love to have. Thanks in advance, I really appreciate the work you do.
@ElegantSudo the issue here (in this thread) isn't to do with not being ES6, it's to do with Phaser being one giant global single var, with no module capability at all, with dependencies to other global based libs. Which makes it a pain to ingest in a module based workflow. Which is why Phaser 3 is fully modular, and itself built with webpack2. The code is still ES5, the module format CJS, but it should make threads like this a thing of the past. ES6 will follow, but first the module based version needs completing. One leads to the other.
@photonstorm ah, that's what I meant (albeit, didn't communicate correctly). Thanks, and on that note, I'm really looking forward to Phaser 3!
@pk-nb Thanks! expose-loader
solution is what I'll work with for now. Looking forward to Phaser 3.
I got it working alrite, but the bundle is a whopping 3.9mb. Has anyone managed to create a webpack config and/or 'require scheme' that can separate phaser into chunks for preloading purpose?
Not sure if you're talking about Phaser 2 or 3, but it sounds too large in either case unless it's including the source map and comments, in which case it sounds about right. Exclude those and it should be significantly smaller. In Phaser 2 you cannot separate the modules out on their own, in V3 you can.
@josfaber Yes. I have been able too keep it chunked in a view. I'm using expose loader as mentioned above, and require.ensure: https://github.com/umeboshi2/infidel/blob/2f23c9a978f6bf0c619f6095439c12ee3bc0b1b8/client/applets/phaserdemo/controller.coffee#L9
Thanks for your replies. I managed to get phaser into a separate bundle, which compresses to 800kb when compiling for production. That will thus be browser-cached inbetween the various pages I'll use it in. I can live with that :)
# webpack.config.js
var path = require("path");
var webpack = require('webpack');
var WebpackUtilsPlugin = require('./plugins/webpackutilsplugin');
// Phaser webpack config
var phaserModule = path.join(__dirname, '/node_modules/phaser-ce/')
var phaser = path.join(phaserModule, 'build/custom/phaser-split.js')
var pixi = path.join(phaserModule, 'build/custom/pixi.js')
var p2 = path.join(phaserModule, 'build/custom/p2.js')
function isExternal(module) {
var context = module.context;
if (typeof context !== 'string') {
return false;
}
console.log(context);
return context.indexOf('node_modules') !== -1;
}
module.exports = {
entry: {
"main": "./app/main.js",
"challenge1": "./app/challenge1/main.js",
"challenge2": "./app/challenge2/main.js",
},
output: {
path: path.join(__dirname, "web/js"),
filename: '[name].bundle.js',
// chunkFilename: '[id].chunk.js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: "vendor",
filename: 'phaser.bundle.js',
minChunks: function(module, count) {
return module.resource && /phaser|pixi|p2/.test(module.resource) && count >= 1
},
})
],
module: {
rules: [
{ test: /pixi\.js/, use: ['expose-loader?PIXI'] },
{ test: /phaser-split\.js$/, use: ['expose-loader?Phaser'] },
{ test: /p2\.js/, use: ['expose-loader?p2'] },
{
'test': /\.js$/,
'loader': 'babel-loader',
'exclude': /node_modules/,
'query': {
'presets': ['env']
}
},
]
},
node: {
fs: 'empty',
net: 'empty',
tls: 'empty'
},
resolve: {
alias: {
'phaser': phaser,
'pixi': pixi,
'p2': p2
}
},
watch: true
};
Earlier I made an (ugly) pull request https://github.com/photonstorm/phaser/pull/1923 that made Phaser work with Webpack, but since 7a6de818e1c8742f0e4e3eb0ffb3dc80a280a0e5 I'm sorry to say that this doesn't work anymore.
I'm getting
from https://github.com/photonstorm/phaser/blob/6139071ebc918ddd8a1201279ebc7c70e645de8e/src/Phaser.js#L357
For repro you can use the Webpack boilerplate found here https://github.com/photonstorm/phaser/pull/1924