espace Posted October 3, 2016 Share Posted October 3, 2016 hi, assuming i have two files. I prefer work with separates files for a question of hierarchy and to understand more simply my code. one file for my effect (like a animation for a text) and the game itself. i would at a certain time invoke a function in my separate file with a argument in my game.js. The problem is that i don't know the good syntax to do this. Could you learn a little more about that ? https://jsfiddle.net/espace3d/senvc2d2/ ///////////////////////////////////////////////////////////////////////////////////// //EFFECT.JS // in a different file for example effect.js var e ={} function draw_e() { e.print_name=function(name){ console.log(name) } return e } ///////////////////////////////////////////////////////////////////////////////////// //GAME.JS // assuming this is my main file for example game.js var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { create: create }); var character var utils // my external file function create() { character={} character.name="teddy" //declaring my variable who'is in a external file utils=draw_e() //this is what i'm looking for character_subfunction=function(Fonction,name){ Fonction(name) // i have also try this : // () => Fonction(name) // but that don't work } character_subfunction(utils.print,character.name) //result must be : teddy but the error is Fonction is not a function } Link to comment Share on other sites More sharing options...
mattstyles Posted October 4, 2016 Share Posted October 4, 2016 You're a little way off there, although, from the code, its pretty tough to work out what you're trying to do. If you want a module system, use a proper one. There is one coming for the browser which will follow commonJS spec, the syntax will differ slightly but it'll be basically the same as the one used by node, so any node tutorials regarding modularisation will be of use. You can use Browserify, Webpack, Rollup or SystemJS (there will be others) to create a browser-ready bundle from your modular code. Or, you can go old school and use some sort of namespacing to try to mitigate global leak and simply include all those files in your html (or, even better, concatenate and, if necessary, minify/uglify them and include just the one file). // Utils.js window.AB = window.AB || {} AB.utils.capitalise = function capitalise (word) { return word.replace(/^./, ch => ch.toUpperCase()) } // Game.js window.AB = window.AB || {} var game = new Phaser.Game(800, 600 /*...*/) function create () { var character = {} character.name = AB.utils.capitalise('dave') /* do something with character */ } In this example we have created a namespace, AB (maybe our game is called Action Blast?), and we are applying most of our code to this namespace. We don't have to, but, we might want to include other third-party code that also leaks globals and we don't want awkward conflicts so we'll leak just the one, note also that I've explicitly tacked our namespace on to window, this is deliberate so that its clear what we are doing. Leaking globals isn't great so we need to call out what we are doing. Note also that with a proper module system you needn't leak anything to the window. Our html includes `utils.js` first and then `game.js` although, this is the other awkward thing about not using a proper module system, inclusion order becomes very important. We have mitigated it a little by using `window.AB = window.AB || {}` but its still a concern, particularly for any consumer of our functions. I'd also suggest poking through the Intro files for Phaser and the Pixi library, both have standalone browser builds that use multiple source files, they are both great examples of how to do this, although more complex than these examples. I guess my point would be, learn how to use Browserify or Webpack, particularly as you sound serious about modularisation, and forget about this awkward way of doing things. Link to comment Share on other sites More sharing options...
espace Posted October 4, 2016 Author Share Posted October 4, 2016 hi mattstyle, Thanks for this explanation. i'm going to study browserify, it look great. there is some good videos tutorials about that. unless I am mistaken there is error in your example file, why do you use utils ? i make this without utils and with my previous snippet and it works according to your specifications. https://jsfiddle.net/82gwzgme/ Link to comment Share on other sites More sharing options...
mattstyles Posted October 4, 2016 Share Posted October 4, 2016 Yes, you are correct, I tried to add a method to the utils object without first declaring the utils object. Doh! I added utils in to show that the utils.js file is responsible for the utils object which it then tacks on to the application namespace (or doesn't, in this case, oops!). You get the theory though, so thats good. I'd still recommend browserify over other methods, its simpler, it tends to just work out of the box and it has many many plugins and presets that handle a drastic amount of use-cases. The only things I've found that are awkward are hot-module-reloading, which is possible, but awkward (it only works with some specific projects anyway). Webpack, rollup et al extoll the virtues of tree-shaking, but, in practise, using techniques to reduce bundle sizes produce minimal gains and break many existing modules, although keep checking back with this because its a real concern for developers working with browsers and it's up to modules to support ways of doing this. (just as an example, I've been testing browserify and rollup, mainly for tree-shaking capability using lodash as a large module to target specific parts of, rollup gave me a fairly small improvement on build size, roughly 5%, but broke some other stuff, whereas I could use a babel plugin with lodash that shaved off well over 60% from the build by performing its own tree-shaking with zero downsides, also note that lodash exposes each method as its own module so with either solution that would have reduced the bundle size even further). Link to comment Share on other sites More sharing options...
mattstyles Posted October 4, 2016 Share Posted October 4, 2016 Oh, something I should mention, browserify (or any of the other module systems) don't work with Phaser, a couple of people have tried but its non-trivial changes to make it work nicely, just include Phaser as a global on the page and run browserify/whatever over the rest of your code. Link to comment Share on other sites More sharing options...
espace Posted October 4, 2016 Author Share Posted October 4, 2016 6 hours ago, mattstyles said: Oh, something I should mention, browserify (or any of the other module systems) don't work with Phaser, a couple of people have tried but its non-trivial changes to make it work nicely, just include Phaser as a global on the page and run browserify/whatever over the rest of your code. Could you tell me a little more about that...it would be nice if you could post à short snippet about that... Link to comment Share on other sites More sharing options...
mattstyles Posted October 5, 2016 Share Posted October 5, 2016 Browserify isn't a massive fan of globals, you have to do a little bit of config to get it playing nicely with globals (although, strictly, nothing in JS can stop you from accessing global variables), it basically wraps all of your modules in closures and references them by id when you want them, thus eliminating globals from your bundle. I think the crux of the problem with using Phaser with browserify is that Phaser relies on a custom build of Pixi (currently) and it expects things to be global, when they aren't it can't do its job. There are custom builds of Phaser and there definitely is a way to change it to make it happen, but, its non-trivial, a few people have tried to require Phaser with a module system and failed (as far as I know) and, given that there is fairly active development in Lazer, and now Phaser 3 as well, these things might well be solved and we can just import Phaser from a module repository, such as npm, until then, the best solution is to just include the script in the page and be confident that the Phaser global will be available when you need it. It's no big deal for one module/framework, or even a few, but its a problem that can grow and get out of hand quickly so you don't, generally, want to be leaking too many globals. Link to comment Share on other sites More sharing options...
espace Posted October 10, 2016 Author Share Posted October 10, 2016 a mini recap to work with prototype and external module wtih the old school method https://jsfiddle.net/espace3d/fjjhoycv/ a friend tell to me that this module loader : systemJs is very used in the world of javascript SystemJs: https://github.com/systemjs/systemjs do you know that, is it compatible with phaser ? Link to comment Share on other sites More sharing options...
mattstyles Posted October 10, 2016 Share Posted October 10, 2016 Its not much used and its quite complex, but, it is a crucial piece of the JS ecosystem as it is likely to form part of the puzzle when modules hit natively in the browser. By all means read up on it, but its far more complex to use than something like browserify, rollup or webpack. The issue it solves is that of delivery, systemjs allows asynchronous loading of assets, which is great as it means proper modularisation in a manner which makes sense to a browser i.e. load only what you need for initial render and save loading more stuff until when you need it. Browserify, rollup and webpack traditionally create single bundles (although they can be made to be smarter) that means that you load everything all in one hit, even if you don't need parts of it until later. Whilst the asynchronous pattern is very attractive, it makes life significantly more difficult and in practise its much easier just to create a single bundle, have you html load that entire bundle and only worry about it when that bundle becomes too large to load happily, the crux here being that you may never reach that stage where your bundle is too large so why bother with the additional complexity if the gains are marginal? I haven't seen Phaser work with any module system, it likes to be global in the page (something to do with how it loads Pixi I think), given that it is a large framework (in terms of features) I wouldn't see this as a real issue and I'd strongly recommend just living with it. Load Phaser into the page, then load your module code, two scripts is unlikely to break the bank. Use a module system to bundle up your code, any one you like and leave Phaser as a global. Link to comment Share on other sites More sharing options...
Recommended Posts