1. Getting Started

Now that you’ve read the Preface and have CoffeeScript installed, what do you say we actually start using it? In this chapter we walk through a few ways that CoffeeScript can be executed and compiled.

I’m going to cover some good ways and some not so good ways to compile and execute your code. Although we won’t be covering the inner workings of CoffeeScript in this chapter, it is definitely an invaluable read as you start to work with CoffeeScript. Knowing the ins and outs of the command-line tools that ship with CoffeeScript will make your life easier, not only as you read this book, but as you start developing your first CoffeeScript applications.

Even if you have played around already with the CoffeeScript command-line tools, there is a good chance you might learn something new in this chapter, so please take a few minutes to read it before jumping straight to Chapter 2, “The Basics.”

The CoffeeScript REPL

CoffeeScript ships with a really powerful REPL1, otherwise known as an interactive console, ready to go so you can start playing with CoffeeScript immediately.

Getting started with the REPL is incredibly easy. Simply type the following into your favorite Terminal window:

> coffee

Then you should see a prompt that looks something like the following:

coffee>

If you see the coffee prompt, we are ready to start playing around with some CoffeeScript.

The alternative for starting the REPL is this:

> coffee -i

or if you really like typing a lot:

> coffee --interactive

Let’s start with a basic example. Type the following into the console:

coffee> 2 + 2

You should be presented with the following answer:

coffee> 4

Congratulations, you’ve just written your very first piece of CoffeeScript!

Okay, let’s try something a little more interesting—something more CoffeeScript-esque. We won’t worry too much about what is happening in the following code (we’ll cover it all in greater length later); let’s just get it to run.

Example: (source: repl1.coffee)


a = [1..10]
b = (x * x for x in a)
console.log b


Output: (source: repl1.coffee)


[ 1, 4, 9, 16, 25, 36, 49, 64, 81, 100 ]


Now that is a lot nicer chunk of CoffeeScript, isn’t it? Briefly, we created a new array and filled it with the integers 1 to 10. Then we looped through the numbers in the array, a, multiplied them by themselves and created a second array, b, containing those new values. Wow, eh? Like I said, I’ll happily explain how all that works later; for now, simply bask in the glory of all the lines of JavaScript you didn’t have to write. But in case you are curious as to what the JavaScript would look like, here it is:

Example: (source: repl1.js)


(function() {
  var a, b, x;

  a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

  b = (function() {
    var _i, _len, _results;
    _results = [];
    for (_i = 0, _len = a.length; _i < _len; _i++) {
      x = a[_i];
      _results.push(x * x);
    }
    return _results;
  })();

  console.log(b);

}).call(this);


As you can see, the REPL can be a fun way to play around and experiment with different ideas. However, not everything is roses in the land of the CoffeeScript REPL. CoffeeScript, as you’ll see, is designed around the concept of whitespace being significant. That leaves us with a bit of a problem when trying to write multiline CoffeeScript in the REPL. The answer comes to us in the form of the character.

Let’s try to write a simple function, add, that takes in two numbers and returns the sum of those numbers. Enter the following code into the REPL line by line:

Example: (source: repl2.coffee)


add = (x, y)->
  x + y
console.log add(1, 2)


Output: (source: repl2.coffee)


3


Notice how at the end of the first line we added a . That tells the REPL that we want to add more lines to that expression. It’s important that you keep adding the for every line you want to add to the expression. The first line that doesn’t end with will be considered the end of the expression, and the REPL will attempt to execute that expression.

It is also important to notice that we still had to indent the line after the so that CoffeeScript was able to properly interpret that line of the expression and put it into its proper place.

Finally, to quit the REPL, simply press ctrl-C and the process will end.

The REPL is a powerful and quick way to try out a few ideas, but as we’ve seen it can get a bit hard to use when dealing with more complex code. Later in this chapter, in the section “Executing CoffeeScript Files,” we’ll discuss how to execute files containing CoffeeScript, which is a more appropriate way of running complex code.

In-Browser Compilation

When developing web applications, a time will come when you want to write some CoffeeScript directly inline in your HTML2 file. CoffeeScript does allow you to do this, and I will show you how. However, I want to caution you against doing such a thing. First, there is a very good reason why practices such as Unobtrusive JavaScript3 have become so popular recently. Although being able to execute CoffeeScript in the browser is nifty, it really is not the best compilation option available to us. By keeping your JavaScript in separate files and out of the HTML layer, you are able to keep your code cleaner and degrade more gracefully in environments that don’t support JavaScript.

At first, writing Unobtrusive JavaScript can be a bit confusing and difficult, but after a while it becomes easier to write, more reusable, and more logical to do so. Using tools like jQuery, you can wait for the page to load and attach all the appropriate JavaScript to the correct objects on the page. However, sometimes you do have to prime the pump, so to speak. Usually this means calling an init method, perhaps passing in some JSON4 to do so. I would encourage you to write this tiny amount of code using pure JavaScript. However, should you really want to write it in CoffeeScript, there is a way to let the browser compile it for you.

Let’s take a look at an HTML file with a bit of CoffeeScript embedded in it.

Example: (source: hello_world.html)


<html>
  <head>
    <title>Hello World</title>
    <script src='http://jashkenas.github.com/coffee-script/extras/coffee-script.js' type='text/javascript'></script>
  </head>
  <body>
    <script type='text/coffeescript'>
      name = prompt "What is your name?"
      alert "Hello, #{name}"
    </script>
  </body>
</html>


Because browsers, at least at the time of this writing, don’t contain native support for CoffeeScript compilation, you will need to include a compiler in your page to use. Fortunately, the CoffeeScript team has one ready and waiting. To include it in your HTML file, add the following line to the head of your HTML file:

<script src='http://jashkenas.github.com/coffee-script/extras/coffee-script.js' type='text/javascript'></script>

You can, of course, pull down the contents of the coffee-script.js file and store it locally in your project, should you wish.

The only other step in getting our inline CoffeeScript to compile in the browser is to make sure that we set the appropriate type on our script tags, like so:

<script type='text/coffeescript'></script>

When the page loads, the CoffeeScript compiler in coffee-script.js will search your HTML document for any script tags with a type of text/coffeescript, compile them into the equivalent JavaScript form, and then execute the compiled JavaScript code.

Caveats

Now that you know how to compile CoffeeScript inline in your HTML document, I would like to point out a few things. First, everything that we discuss in this book, in terms of scope, anonymous function wrappers, and so on, all holds true when compiling CoffeeScript in this fashion. So it’s important to keep this in mind when writing your code like this.

Second, and this is probably the big one to take away here, is that this is not a particularly fast way of compiling your CoffeeScript. When deploying this to production, it means all your users will have to download an extra 162.26KB file to compile your CoffeeScript. Then after the page loads, the compiler has to go through the page looking for the text/coffeescript tags, compile them, and then execute them. That’s not a very good user experience.

Armed with this knowledge, I’m hoping you choose the right path and compile your CoffeeScript offline before deploying to production.

Command-Line Compilation

Although being able to execute CoffeeScript in the browser is useful and fairly easy, it really is not the best compilation option available to us. We should be compiling our CoffeeScript before we serve it up the on the Web. However, it is entirely possible that you are writing a Node application or some other server-side application that won’t be in a browser, so browser compilation won’t work there.

So how best should we compile our CoffeeScript? Great question. You will find a lot of third-party libraries that will compile your CoffeeScript files for you (in different languages and on various platforms), but it is important to understand how to do it yourself, so you can write your own compilation scripts, should you need to.

The compile Flag

Let’s start with the most important flag to the coffee command, -c. The -c flag will take the CoffeeScript file you pass to it and compile it out to a JavaScript file for you in the same location. This is how I compiled the source code examples in this book.

Let’s go ahead and create a simple file called hello_world.coffee and make it look like this:

greeting = "Hello, World!"
console.log greeting

Now we can compile that file like so:

> coffee -c hello_world.coffee

That should compile our CoffeeScript file into a new JavaScript file in the same directory called hello_world.js. The contents of hello_world.js should look like this:

(function() {
  var greeting;

  greeting = "Hello, World!";

  console.log(greeting);

}).call(this);

Our hello_world.js JavaScript file is ready for production! Time for a cup of tea.

The CoffeeScript CLI

We’ve played with the REPL and have learned how to compile our CoffeeScript using the command line coffee tool, but the coffee command offers a few other interesting options that we should quickly look at. To see a full list of what the coffee command has to offer, enter the following into your terminal:

> coffee --help

You should see output similar to the following:

Usage: coffee [options] path/to/script.coffee

  -c, --compile      compile to JavaScript and save as .js files
  -i, --interactive  run an interactive CoffeeScript REPL
  -o, --output       set the directory for compiled JavaScript
  -j, --join         concatenate the scripts before compiling
  -w, --watch        watch scripts for changes, and recompile
  -p, --print        print the compiled JavaScript to stdout
  -l, --lint         pipe the compiled JavaScript through JavaScript Lint
  -s, --stdio        listen for and compile scripts over stdio
  -e, --eval         compile a string from the command line
  -r, --require      require a library before executing your script
  -b, --bare         compile without the top-level function wrapper
  -t, --tokens       print the tokens that the lexer produces
  -n, --nodes        print the parse tree that Jison produces
      --nodejs       pass options through to the "node" binary
  -v, --version      display CoffeeScript version
  -h, --help         display this help message

Let’s take a look at some of those options now.

The output Flag

Although compiling the JavaScript file in the same directory as the CoffeeScript is all right when you are just playing around, chances are you probably want to keep the files in separate directories. So how do we compile our hello_world.coffee file into, for instance, public/javascripts?

The answer is simple: we need to add the -o to our terminal command:

> coffee -o public/javascripts -c hello_world.coffee

If you check your public/javascripts directory, you’ll find your newly compiled hello_world.js file waiting there for you.

One thing that the -o flag does not let you do is change the name of the file. The compiled JavaScript file will have the same name as the original CoffeeScript file, except with the .js extension instead of the .coffee extension. Because you cannot rename the file using the coffee command, you’ll either want to rename your original file or write a script that does both the compilation of your CoffeeScript file and then renames them to something more to your liking.

The bare Flag

As you’ll see later in the book, when CoffeeScript compiles, it wraps the generated JavaScript in an anonymous function. Because we’ll cover this topic in more detail in Chapter 2, I won’t go into it here. What follows is an example of that anonymous function being wrapped in the generated JavaScript code:

Example: (source: hello_world.js)


(function() {
  var greeting;

  greeting = "Hello, World!";

  console.log(greeting);

}).call(this);


Now, at times, for whatever your reasons, you may not want that anonymous function wrapper. In those cases we can pass the CoffeeScript compiler the -b flag.

> coffee -b -c hello_world.coffee

That will compile our CoffeeScript into the following JavaScript:

Example: (source: hello_world_bare.js)


var greeting;

greeting = "Hello, World!";

console.log(greeting);


Now that you know how to remove the anonymous wrapper, I want to caution you about doing so. There are a lot of very good reasons as to why it is being generated in the first place. If you’d like to find out more about this anonymous function, see Chapter 2.

The print Flag

Sometimes when you’re compiling your CoffeeScript files, what you really want is to see the output of the file. Fortunately, the coffee command has you covered with the -p flag:

> coffee -p hello_world.coffee

This will print out to your terminal something like the following:

(function() {
  var greeting;

  greeting = "Hello, World!";

  console.log(greeting);

}).call(this);

This can be incredibly useful for debugging purposes or as a great learning tool with CoffeeScript. By comparing your CoffeeScript against the compiled JavaScript (as we do in this book), you can start to understand what CoffeeScript is doing under the covers. This was a huge help for me when I was originally learning CoffeeScript. It has also helped me to become a better JavaScript developer by investigating some of the choices that the complier has made.

The watch Flag

As you are developing your CoffeeScript projects, you’re not going to want to keep going to the command line to keep compiling. To make this a little easier for you, CoffeeScript gives you the optional -w parameter to the coffee command. With this parameter you can tell the coffee command to keep watching your CoffeeScript files and if they change to recompile them. Here is an example:

> coffee -w -c app/assets/coffeescript

With this command, anytime a .coffee file is touched5 in the app/assets/coffeescript directory, or any subdirectories, it is automatically compiled.

As of CoffeeScript 1.2.0, the -w will watch for new files that have been added to a watched directory. In my experience, however, it can be quite buggy because of some underlying Node issues. Hopefully, these issues will be worked out by the time you read this. However, plenty of third-party tools exist that are designed to listen to file system events, such as files being added and removed. My personal favorite, as of the time of writing, is Guard.6 It’s a Ruby gem that lets you listen for these types of events and execute some custom code, such as compiling CoffeeScript files, when these events occur.


Tip

In addition to Guard, you might also want to check out Jitter7 by Trevor Burham. It accomplishes a similar goal of watching and compiling all your CoffeeScript files. It is also written using CoffeeScript, so that’s not a bad thing.


Executing CoffeeScript Files

We’ve covered various ways to compile our CoffeeScript and have discussed some of the options we can pass into the coffee command when compiling CoffeeScript, but what about just executing the CoffeeScript file in question? Perhaps you are writing a web server using CoffeeScript or even a simple script that does some basic number crunching. You could compile our scripts using the tools you’ve already learned about, then link to them in an HTML file, and finally, run them in a browser. That would work for a simple script, but not for something more complex like a web server. Nor is it a practical idea.

To help with this situation, the coffee command lets us execute our CoffeeScript files like this:

> coffee hello_world.coffee

Most of the examples that we look at throughout this book can be run in just this fashion (unless otherwise noted).

Other Options

There are a few other options such as -n and -t. Although these options can give you some really interesting output and insight into how CoffeeScript compiles your code, they won’t really be of help to us during the course of this book so I won’t be covering them here. I do, however, encourage you to take some time to run the extra options to see what they produce. You can find out more about these options by reading the annotated source8 for CoffeeScript online.

Wrapping Up

In this chapter we’ve taken a tour of the different ways that we can compile and execute our CoffeeScript code. We’ve looked at the pros and cons of the ways that CoffeeScript can be compiled and are now armed with the knowledge we need to be able to play with the examples in the rest of this book. Finally, we dug into the coffee command to learn the most important options and parameters we can pass to it.

Notes

1. Read-eval-print loop - http://en.wikipedia.org/wiki/Read-eval-print_loop

2. http://en.wikipedia.org/wiki/Html

3. http://en.wikipedia.org/wiki/Unobtrusive_JavaScript

4. http://en.wikipedia.org/wiki/Json

5. Touching a file means lots of different things on different operating systems, but usually just saving the file is enough of a “touch” to trigger the -w into doing its magic.

6. https://github.com/guard/guard

7. https://github.com/TrevorBurnham/jitter

8. http://jashkenas.github.com/coffee-script/documentation/docs/command.html

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.137.184.102