Talking about HTML5, Javascript, Phaser and TypeScript.
With Phaser4 version to be released hopefully not that late, it’s recommended to start coding in TypeScript, but before even thinking about TypeScript, it’s time to learn something about Node.js and npm.
Why? Because we’ll need them to build, pack and distribute our HTML games, and we can use them even if we aren’t coding in TypeScript yet.
“Why should I install all this stuff just to run a JavaScript file?”
Yes, this was the same question I asked to myself, just like some years ago I asked to myself why should I install a web server just to run plain JavaScript files.
The short answer would be: because this is the only way for you to code using TypeScript, but you’ll see a lot of even more interesting reasons to jump into these “new” technologies.
Time to reply to the even more important question: what is Node.js?
Node.js is an open-source, cross-platform, back-end JavaScript runtime environment able to execute JavaScript code outside a web browser.
It can be used to write server-side scripts using JavaScript rather to use one language for server-side, like PHP, and one language for client-side, like JavaScript itself.
Let’s start checking if you already have Node.js installed. Open a shell and write:
node -v
This should prompt Node version.
If you get an error like this one, then you don’t have Node.js installed.
Let’s also check npm version with:
npm -v
Which should give another error if the previous command wasn’t successful.
Never mind! We are going to install both Node.js and npm at this link: https://nodejs.org/
Choose the one named “Current” and install the package.
After the installation, you should be able to get results both for
node -v
and
npm -v
Like in this example:
Obviously, you should install again Node.js if the version prompted is outdated.
Ok, now we have Node.js installed, what now? We said we are able to execute JavaScript outside a web bowser, so let’s have a try: create a file with this content:
console.log("I am prompting this from command line");
Then save as testnode.js
and launch it with node this way:
node testnode.js
And you should get the text prompted in your shell:
Great! But did we install Node.js just to prompt some stuff? No, there is much more you can do, let’s see this script taken from the official Node.js “About” page:
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end('Hello World');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
Let’s copy it into testnode.js
, launch it and see what happens:
There’s a server running at http://127.0.0.1:3000/
it says, let’s point the browser to that address:
And here we go, we were able to set up a web server.
It would be nice if we could launch a page from the web server, so let’s try to change testnode.js this way:
const http = require('http');
const fs = require('fs')
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.writeHead(200, { 'content-type': 'text/html' })
fs.createReadStream('index.html').pipe(res)
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
As you can see at line 8, we try to read a file called index.html, so let’s create it and write some content in it:
<h1>Hello World, I am working</h1>
Let’s test the script again, refresh http://127.0.0.1:3000/
and let’s see what happens:
At this time, we can try to load a Phaser game into a Node.js web server.
As you should know, you can’t run complex Phaser games outside a web server, due to browser security protocols, unless you don’t use any external resource such as images or sounds.
But this DROP’d prototype won’t work outside a web server, so let’s copy the source in a folder called phaser
, add a file called launcher.js
and copy/paste this script by The Jared Wilcurt which has everything we need without forcing us to reinvent the wheel.
// npm-Free Server by The Jared Wilcurt
// All you need to run this is an installed copy of Node.JS
// Put this next to the files you want to serve and run: node server.js
// Require in some of the native stuff that comes with Node
var http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');
// Port number to use
var port = process.argv[2] || 8000;
// Colors for CLI output
var WHT = '\033[39m';
var RED = '\033[91m';
var GRN = '\033[32m';
// Create the server
http.createServer(function (request, response) {
// The requested URL, like http://localhost:8000/file.html => /file.html
var uri = url.parse(request.url).pathname;
// get the /file.html from above and then find it from the current folder
var filename = path.join(process.cwd(), uri);
// Setting up MIME-Type (YOU MAY NEED TO ADD MORE HERE) <--------
var contentTypesByExtension = {
'.html': 'text/html',
'.js': 'text/javascript',
'.json': 'text/json',
'.svg': 'image/svg+xml'
};
// Check if the requested file exists
fs.exists(filename, function (exists) {
// If it doesn't
if (!exists) {
// Output a red error pointing to failed request
console.log(RED + 'FAIL: ' + filename);
// Redirect the browser to the 404 page
filename = path.join(process.cwd(), '/404.html');
// If the requested URL is a folder, like http://localhost:8000/catpics
} else if (fs.statSync(filename).isDirectory()) {
// Output a green line to the console explaining what folder was requested
console.log(GRN + 'FLDR: ' + WHT + filename);
// redirect the user to the index.html in the requested folder
filename += '/index.html';
}
// Assuming the file exists, read it
fs.readFile(filename, 'binary', function (err, file) {
// Output a green line to console explaining the file that will be loaded in the browser
console.log(GRN + 'FILE: ' + WHT + filename);
// If there was an error trying to read the file
if (err) {
// Put the error in the browser
response.writeHead(500, {'Content-Type': 'text/plain'});
response.write(err + '\n');
response.end();
return;
}
// Otherwise, declare a headers object and a var for the MIME-Type
var headers = {};
var contentType = contentTypesByExtension[path.extname(filename)];
// If the requested file has a matching MIME-Type
if (contentType) {
// Set it in the headers
headers['Content-Type'] = contentType;
}
// Output the read file to the browser for it to load
response.writeHead(200, headers);
response.write(file, 'binary');
response.end();
});
});
}).listen(parseInt(port, 10));
// Message to display when server is started
console.log(WHT + 'Static file server running at\n => http://localhost:' + port + '/\nCTRL + C to shutdown');
Now move into phaser folder and type
node launcher.js
And now pointing your browser at http://localhost:8000/
you will see your Phaser game running with no need of external web servers.
You may say that this is actually an external web server, and you’re right, but this is only the beginning of the fantastic journey which will bring us to the magic land of TypeScript and Phaser. And what about npm? We’ll see it in next step of the series, meanwhile download the source code of the Phaser project with the Node.js script.
Never miss an update! Subscribe, and I will bother you by email only when a new game or full source code comes out.