Build & Bundlers

To get started, first install Excalibur through npm (TypeScript typings are best supported in npm):

npm install excalibur

TypeScript Configuration

In a TypeScript project, you can reference Excalibur with the ES6 import style syntax:

// Excalibur is loaded into the ex global namespace
import * as ex from 'excalibur'

or

// Excalibur is loaded into the ex global namespace
import { Actor, Engine } from 'excalibur'

TSConfig

We have a base recommended tsconfig.json that the TypeScript compiler uses as configuration. In this example we assume all the source is in a ./src/ directory.

{
  "include": ["src/**/*"],
  "compilerOptions": {
    /* Basic Options */
    "target": "es2015" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
    "module": "es2015" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
    /* Specify library files to be included in the compilation. */
    "lib": [
      "dom",
      "es5",
      "es2015.Proxy",
      "es2015.promise",
      "es2015.collection",
      "es2015.iterable",
      "es2015"
    ],

    /* Strict Type-Checking Options */
    "strict": true /* Enable all strict type-checking options. */,

    /* Module Resolution Options */
    "moduleResolution": "node" /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */,
    "baseUrl": "./src" /* Base directory to resolve non-absolute module names. */,
    "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,

    /* Advanced Options */
    "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
  }
}

In a module loader system, such as Webpack or Parcel, it will automatically bundle Excalibur. See the webpack example repo or parcel repo

To support tree-shaking, you should use named imports:

import { Actor } from 'excalibur'

Excalibur doesn't do the best optimization to support tree-shaking--likely you'll end up importing everything at the moment but this is slowly getting better.

Parcel

Parcel is by far the easiest way to get a bundler up and running with excalibur. We recommend looking at the template.

Adding an import "regenerator-runtime/runtime"; in your entry file is needed to force parcel to understand async/await inside excalibur

Using npm to install parcel, excalibur, and typescript

npm install parcel-bundler excalibur typescript

Configure you tsconfig.json

tsc --init

Build your game script

// ./src/index.ts
const game = new Engine({
  width: 600,
  height: 400,
})

game.start()

Include the typescript file in your html

<html>
  <head></head>
  <body>
    <script src="./src/index.ts" />
  </body>
</html>

Build and run with parcel!

parcel index.html --no-autoinstall

Webpack

Webpack is the battleship solution, and if you need a lot of control over your build process, this might be the way to go.

Configuring webpack is not for the faint of heart, we recommend thoroughly reading webpack's documentation on how to understand and configure webpack.

Our template is a good starting point.