├── .babelrc ├── .gitignore ├── LICENSE ├── README.md ├── index.html ├── package-lock.json ├── package.json ├── src ├── assets │ └── logo.png ├── index.js ├── phaser-core.js ├── phaser-custom-sprite-loader.js ├── phaser-custom.js └── phaser-full.js └── webpack ├── base.js └── prod.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/env", { 4 | "targets": { 5 | "browsers": [ 6 | ">0.25%", 7 | "not ie 11", 8 | "not op_mini all" 9 | ] 10 | }, 11 | "modules": false 12 | }] 13 | ], 14 | } 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # System and IDE files 2 | Thumbs.db 3 | .DS_Store 4 | .idea 5 | *.suo 6 | *.sublime-project 7 | *.sublime-workspace 8 | 9 | # Vendors 10 | node_modules/ 11 | 12 | # Build 13 | dist/ 14 | /npm-debug.log 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Richard Davey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Phaser 3 Webpack Project Template with custom Phaser Build 2 | 3 | A Phaser 3 project template with ES6 support via [Babel 7](https://babeljs.io/) and [Webpack 4](https://webpack.js.org/) 4 | that includes hot-reloading for development and production-ready builds. 5 | 6 | Loading images via JavaScript module `import` is also supported, or are copied from the `assets` folder. 7 | 8 | ## Requirements 9 | 10 | [Node.js](https://nodejs.org) is required to install dependencies and run scripts via `npm`. 11 | 12 | ## Available Commands 13 | 14 | | Command | Description | 15 | |---------|-------------| 16 | | `npm install` | Install project dependencies | 17 | | `npm start` | Build project and open web server running project | 18 | | `npm run build` | Builds code bundle with production settings (minification, uglification, etc..) | 19 | 20 | ## Writing Code 21 | 22 | After cloning the repo, run `npm install` from your project directory. Then, you can start the local development 23 | server by running `npm start`. 24 | 25 | After starting the development server with `npm start`, you can edit the `src/index.js` files 26 | and webpack will automatically recompile and reload your server (available at `http://localhost:8080` 27 | by default). 28 | 29 | ## Customizing the Template 30 | 31 | ### How to import a custom Phaser build 32 | 33 | If you look in the `src/index.js` file, you will see that Phaser has been imported at the top of the file: 34 | 35 | ```javascript 36 | import Phaser from './phaser-custom-sprite-loader'; 37 | ``` 38 | 39 | Note that you do not import the _entire_ Phaser package, but rather a custom entry point that contains only the 40 | parts your game needs. If you open the file `phaser-custom-sprite-loader.js` you'll see the modules that have 41 | been exposed: 42 | 43 | ```javascript 44 | require('../node_modules/phaser/src/polyfills'); 45 | 46 | var CONST = require('../node_modules/phaser/src/const'); 47 | var Extend = require('../node_modules/phaser/src/utils/object/Extend'); 48 | 49 | var Phaser = { 50 | 51 | Cameras: { 52 | Scene2D: require('../node_modules/phaser/src/cameras/2d') 53 | }, 54 | Events: require('../node_modules/phaser/src/events/EventEmitter'), 55 | Game: require('../node_modules/phaser/src/core/Game'), 56 | GameObjects: { 57 | DisplayList: require('../node_modules/phaser/src/gameobjects/DisplayList'), 58 | UpdateList: require('../node_modules/phaser/src/gameobjects/UpdateList'), 59 | 60 | Image: require('../node_modules/phaser/src/gameobjects/image/Image'), 61 | Sprite: require('../node_modules/phaser/src/gameobjects/sprite/Sprite'), 62 | 63 | Factories: { 64 | Image: require('../node_modules/phaser/src/gameobjects/image/ImageFactory'), 65 | Sprite: require('../node_modules/phaser/src/gameobjects/sprite/SpriteFactory') 66 | }, 67 | 68 | Creators: { 69 | Image: require('../node_modules/phaser/src/gameobjects/image/ImageCreator'), 70 | Sprite: require('../node_modules/phaser/src/gameobjects/sprite/SpriteCreator') 71 | } 72 | }, 73 | Loader: { 74 | FileTypes: { 75 | ImageFile: require('../node_modules/phaser/src/loader/filetypes/ImageFile') 76 | }, 77 | LoaderPlugin: require('../node_modules/phaser/src/loader/LoaderPlugin') 78 | }, 79 | Math: { 80 | Between: require('../node_modules/phaser/src/math/Between') 81 | }, 82 | Tweens: require('../node_modules/phaser/src/tweens') 83 | }; 84 | 85 | Phaser = Extend(false, Phaser, CONST); 86 | 87 | module.exports = Phaser; 88 | ``` 89 | 90 | This file is creating a custom Phaser API bundle, so that only those APIs listed (and those required internally by them) are bundled together. This can dramatically decrease the size of your final bundle. There are several custom build entry points included in this project template. Use which-ever one you need, or take one and customise it as you see fit. Full instructions on creating custom entry points can be found below. 91 | 92 | ### Babel 93 | 94 | You can write modern ES6+ JavaScript and Babel will transpile it to a version of JavaScript that you 95 | want your project to support. The targeted browsers are set in the `.babelrc` file and the default currently 96 | targets all browsers with total usage over "0.25%" but excludes IE11 and Opera Mini. 97 | 98 | ``` 99 | "browsers": [ 100 | ">0.25%", 101 | "not ie 11", 102 | "not op_mini all" 103 | ] 104 | ``` 105 | 106 | ### Webpack 107 | 108 | If you want to customize your build, such as adding a new webpack loader or plugin (i.e. for loading CSS or fonts), you can 109 | modify the `webpack/base.js` file for cross-project changes, or you can modify and / or create 110 | new configuration files and target them in specific npm tasks inside of `package.json'. 111 | 112 | ## Deploying Code 113 | 114 | After you run the `npm run build` command, your code will be built into a single bundle located at 115 | `dist/bundle.min.js` along with any other assets you project depended. 116 | 117 | If you put the contents of the `dist` folder in a publicly-accessible location (say something like `http://mycoolserver.com`), 118 | you should be able to open `http://mycoolserver.com/index.html` and play your game. 119 | 120 | # Creating Custom Phaser 3 Builds 121 | 122 | By default, Phaser will include pretty much everything, especially if you just require or import the main entry point. This will add 770KB of minified JavaScript to your bundle which is a considerable amount, especially if you aren't even using a large chunk of it. However, you can choose what you actually need in your bundle to a very granular degree. It just takes a little configuration to do it. 123 | 124 | To create custom builds you're going to need [webpack](https://webpack.js.org/). If you've no experience with webpack it'd be best to go and learn how it works before carrying on, as Phaser is built specifically with it. Other bundlers, like Parcel, may also work but it's up to you to translate this guide into their respective formats. 125 | 126 | The important thing to remember is that the Phaser module entry point, as defined in webpack, controls the whole structure of the exposed API. That is, everything it includes is made available under the Phaser namespace. It literally defines which features are included in the library. That's an important distinction you should understand: it controls what is available in the library, it's not meant as an entry point for a _project_. 127 | 128 | ## Building Phaser 129 | 130 | This guide is based on creating a custom build of Phaser 3.11. When newer versions ship, it'll change slightly, because more things will be available to bundle in, but the core concept will remain exactly the same. 131 | 132 | To start with I'd recommend you [clone this template repo](https://github.com/photonstorm/phaser3-custom-build). It will save a whole bunch of time getting set-up. Clone it, then `npm install` to grab the dependencies. You're now ready to do a custom build. 133 | 134 | If you issue the command `npm run build` (or `webpack` if you've got it available globally) from the project folder then it'll create a custom build into the `dist` folder. This file is called `phaser-custom.js`. Inside the `test` folder you'll find an `index.html` file. Open this in a browser via an http server, or with local file permissions enabled, and you should see the following: 135 | 136 | []() 137 | 138 | If you're wondering where on earth the Star Wars logo is coming from that's a valid question :) Let's break it down. 139 | 140 | The webpack config in the template uses the file [phaser-custom.js](https://github.com/photonstorm/phaser3-custom-build/blob/master/phaser-custom.js) as its entry point. Here's the complete file: 141 | 142 | []() 143 | 144 | If you look at the file, or the above image, you'll see it defines what's available in the Phaser namespace. It starts by including the standard polyfills and CONSTs. Then it pulls in the 2D Camera system, the Events, the Game, the Graphics object and finally one Math function called Between. 145 | 146 | This is concluded by merging in the constants and exporting it globally. Combined with the webpack config this will build into the phaser-custom.js bundle which will have everything Phaser needs to run, plus the extras identified above. By default Phaser doesn't include a camera system or any Game Objects, which makes the 'base' use somewhat limited. So in this case we've added the Graphics object, because at the very least we can render something with that. 147 | 148 | The `GraphicsFactory` function is what allows you to use the command `this.add.graphics` from within a Scene. You could exclude this to save a couple of KB if you wish, but then you'd have to alter your code to create a Graphics instance directly and add it to the Display List. 149 | 150 | In the `test/index.html` file you'll see the code for our demo. All it does is create an 800 x 600 game instance and then renders the Star Wars logo to the Graphics object. It's not exactly a game but it demonstrates that, fundamentally, everything is working. 151 | 152 | If you look in the `dist` folder you'll see that the `phaser-custom` file is 274 KB minified, or 71 KB gzipped. So, it's _significantly_ smaller than the default build that Phaser ships with. 153 | 154 | ## Tweaking the Custom Build 155 | 156 | So, how do you now edit the custom build to include the ability to do something useful like load images and display them? To do this we need two extra things added to our package: Sprites and the File Loader, otherwise, we can't get the files into Phaser. Here is a tweaked version of the `phaser-custom.js` file from above. You can find this in the repo called [phaser-custom-sprite.js](https://github.com/photonstorm/phaser3-custom-build/blob/master/phaser-custom-sprite.js): 157 | 158 | []() 159 | 160 | If you look at the file above you'll see we've added in the Image and Sprite Game Objects (and removed Graphics) and also added the Loader module. This pulls in the entire Loader and all possible File Types, which is actually overkill for this bundle, so I'll show you how to refine that shortly. For now, though, it will do what we need. Issue the command `npm run buildsprite` and it'll build a new bundle to the `dist` folder. Launch the file `test/indexsprite.html` and you should get the following: 161 | 162 | []() 163 | 164 | Taa-da, working Sprites and image loading! The bundle size is now 78 KB min+gz, which is 7 KB bigger than our Graphics only bundle, but that's to be expected as we've added the whole Loader module to our build and a couple of meaty Game Objects too. 165 | 166 | Let's refine it a little bit though. We really don't need all of the file types the Loader supports. In fact, for this test, we literally only need one: the Image loader. Let's tweak our entry point so it includes only the LoaderPlugin and the Image File Type: 167 | 168 | []() 169 | 170 | If we re-run the build command our new minified file is 284 KB which is 19 KB less than before. It's not just about file size, though, that's less JavaScript for the browser to process when it's launching your game for the first time too. 171 | 172 | How do you know which things to include back in the entry point? You can work it out by looking at the `phaser.js` and `phaser-core.js` files in the root src folder of the main Phaser repo. Using those, plus just browsing the source folders for yourself, you can quickly find what you need. 173 | 174 | There's still quite a lot of modules being included that we may not require though. We can visualize that by creating a webpack profile. Use the command `npm run buildlog`. This will build Phaser and also create a JSON file that details the build process. You can upload this JSON file to the online [webpack analyzer](http://webpack.github.io/analyse/). I've included a json file in the repo so you can try it out for yourself. Just [download it from here](https://github.com/photonstorm/phaser3-custom-build/blob/master/webpack.build-log.json), then go to the webpack analyzer and upload it. After a short while it will generate a report. Click on 'modules' to view the module tree: 175 | 176 | []() 177 | 178 | All of the modules are listed below the interactive tree. Click any node on the tree to see what is requiring that module and how many dependencies it has. Let's pick a particularly busy node: 179 | 180 | []() 181 | 182 | As we can see, lots of modules include the entire Array Utils package. This isn't a bad thing in itself, because it's a pretty compact and widely used area of the API, but this exploration process did highlight a lot to me. If you look at the Game module you'll see it pulls in plenty of things. The Texture Manager, the Sound Manager, the Animation Manager. All the things it expects to need in order to operate. Yet, the Sound Manager is entirely optional - we could easily hide that behind a custom build flag and it'd stop including 140 KB worth of un-minified source, because if you're literally not using it, why even bother to have it in the API? The same can be said for a number of other systems, such as the Animation Manager. The Device module could be made into a much more compact version that only includes checks that Phaser needs to boot-up, too. 183 | 184 | In short, I'm quite happy that it's really easy to create a significantly smaller version of Phaser 3 with very little effort on your part. Use the custom build template and smash away parts of the API you don't need and get your games even leaner. This is especially important for Facebook Instant Games, where time-to-play needs to be as tiny as possible. Reducing your build from several hundred KB down to 70 KB certainly gets you a lot further along that path. 185 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "phaser3-project-template-custom-build", 3 | "version": "1.0.0", 4 | "description": "Phaser 3 Project Template with custom build of Phaser", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "build": "webpack --config webpack/prod.js", 8 | "start": "webpack-dev-server --config webpack/base.js" 9 | }, 10 | "repository": { 11 | "type": "git", 12 | "url": "git+https://github.com/photonstorm/phaser3-project-template-custom-build.git" 13 | }, 14 | "author": "Richard Davey