Next steps in Nodejs & Grunt

Welcome back to the next tutorial on using Nodejs and Grunt to build a simple game server. Last time we left off with just getting grunt setup and installed a few basic packages. The watch package helps us automate watching our development directory (src) and when a file was added or modified it would copy it to our build folder. In this part of the tutorial we will continue adding a couple more packages that will help us manage the build process and then send it to our test server.

Open a command prompt, for those Windows users just right click on your window icon and click Command Prompt. We will want to install the following npm packages to help with more of the automation process. Here is a list we will be adding with a very brief explanation:

  • grunt-contrib-jshint - Used to evaluate our JavaScript code and make sure it is valid before we move onto minimizing it.
  • grunt-contrib-uglify - No we aren’t going to hit our project with an ugly stick this package will compress our JavaScript code into one line which makes it very difficult to read. Hence the term uglify.
  • grunt-bundle - We will use this package to break our project into multiple files and then during the build process combine them together so we don’t have to add a bunch of script tags to our html source files.
  • grunt-sftp-deploy – There are several packages that you can use to upload your code but since I wanted to have a secure and easy way to upload my files I found this simple package that is easy to use.

That should be it for now, in the command prompt type the following npm commands:

C:\grunt>npm install grunt-bundle --save-dev
C:\grunt>npm install grunt-contrib-jshint --save-dev
C:\grunt>npm install grunt-contrib-uglify --save-dev
C:\grunt>npm install grunt-sftp-deploy

Now with all these packages added we should be able to now setup our grunt config file to automate many of the pesky tasks we would have to do manually without grunt. The first thing we are going to do is setup a way to combine all our source files into a JavaScript package file. This will help so we only have to test one file instead of all the small files we will be creating.

Add the following lines of code to your Gruntfile.js file in the initConfig function:

		bundle: {
			core:{
				src: 'src/<%= pkg.name %>.js',
				dest: 'build/js/<%= pkg.name %>-<%= pkg.version %>.js'
			}
		},

In this example code we are using a feature that lets us dynamically give a name to our final output package. For my final files it is nice to add a version number so that I know when a major change has occurred and I don’t have to remember to rename it later. Anyways anything between the <%= and %> tags will get interpreted by grunt. You will see this is later addition configuration settings. Also it is important to note that we can add addition bundle sub tasks to help break our project up event more but for now we just need the one core task.

Now we will need to modify the copy function so it doesn’t take all our JavaScript source files and copy them over. But we still may want the copy function to find any html files and copy it to the build folder for us. So here is the new copy configuration settings:

		copy: {
			main: {
				files: [
					{
						expand: true,
						cwd: 'src',
						src: ['*.html'],
						dest: 'build/'
					}
				]
			}
		},

the only thing that changed was the src setting, it was '**' and now it is '*.html'. If you’re having problems you can always check the github repository for the final working settings.

Now we need to setup our main entry point file that will be used in the bundle task. This file will just contain some basic require calls which will help adding new files to the project quick and easy. In the src folder create a file called “game-engine.js”. The contents of this file should look something like this:

//game-engine.js
import 'core';

When bundle looks at this file it will see that we want to include all the module files in core. To make things really simple in the JS directory create a folder called “core”. Any file we put in this folder will be automatically added to our bundled file. As we make new directories we will just need to modify this file to require these files and make a browser friendly file for us.

Now that we have the basic project setup go ahead and start grunt and run the watch task. To do this type in the following command in the command prompt:

C:\grunt>grunt watch

Grunt will respond by saying:

Running “watch” task
Waiting…

Now when we add, modify or delete a file from our JS folder it will run our defined tasks. To test this we will need to create a new file in the core directory. Create a file under “C:\grunt\src\js\core” called engine.js and add these lines of code to the file and save it:

//engine.js
function gEngine(cfg){

}

Once you save the file our bundled file should be created. Check the C:\grunt\build\js folder and you should see a new file in this folder. The cool thing about watch is we can continue to make change the Gruntfile.js and it will pick them up and run the latest configurations.

We just have a couple of modules to add before we are ready to move onto building the game engine. These are jshint which will perform some basic java script validation and then uglify to minimize our final output code. To add these packages it is a two step process. First we need to load them in grunt so add the following two line of code to the Gruntfile.js

	g.loadNpmTasks('grunt-contrib-jshint');
	g.loadNpmTasks('grunt-contrib-uglify');

Next we need to add code the initConfig function that builds tasks in grunt for these two new packages. The first one we will add is the jshint task, which I like to run on the final bundled code so add these lines of code in the initConfig section:

		jshint:{
			src: ['<%= bundle.core.dest %>', 'Gruntfile.js'],
		},

This line of code takes the output of the combiner and then uses it to validate our newly created code. Optionally we could add all source JS file to the jshint tasks so that we could get a better idea of specifically which file is causing problems. So modify the src line to also include all our JavaScript files under src/js. We will also need to make sure we don’t try and validate the main file used in our bulde task because it will throw errors due to not using EM6. The second src file tells jshint to ignore out main package JavaScript file. Here is what it should look like:

src: ['src/js/**/*.js', '!src/js/<%= pkg.name %>.js','<%= bundle.core.dest %>', 'Gruntfile.js'],

Now that is done we can add the final step to the process which is to minimize our code. Add the following lines of code to the initConfig function in our Gruntfile.js file:

		uglify:{
			options:{
				banner: '/*Your banner here*/',
				sourceMap: true
			},
			build:{
				files: {
					'build/js/<%= pkg.name %>-<%= pkg.version %>.min.js': ['<%= bundle.core.dest %>']
				}
			}
		},

Once this is added to the Gruntfile you should see the watch thread take over and make a minified version of our library. That is it for this version of the project. Make sure you check out the github repository for the complete project.