It took a long time to occur, but I finally began to read up and look into CoffeeScript recently and I'm extremely happy with that decision. The only downside that I had experienced in my initial use was when I inevitably had to debug my code in the developers console of Chrome. At that point I was looking at the compiled JavaScript, which is still very readable, but it didn't map line for line with the CoffeeScript.
After a little bit of investigation I discovered that the CoffeeScript compiler can create source maps for the compiled JavaScript files. The source map allows the developers console to know which part of the compiled JavaScript maps up to the original CoffeeScript source code. The source code mapping is accomplished by converting lines of code to Base64 VLQ (Variable Length Quantity) values. There's an excellent explanation on the HTML5Rocks website, that breaks down how Base64 VLQ values are calculated and then how they map from the the source map to individual files. With the source map, compiled JavaScript file, and the source code written in CoffeeScript it is now possible to debug CoffeeScript in the developers console!
Using Source Maps in the Google Chrome Developer's Tools
Now that we know all of the pieces that are needed to enable this amazing utility, how are they put together to obtain the desired result? At the time of this is being written, I'm using Google Chrome version 39.0.2171.65 (64-bit) and version 1.8.0 of the coffee-script
npm module. For this project I wrote a basic CoffeeScript solution for the Fibonacci sequence that will have the source code provided at the end of the post.
First thing that will be configured is enabling the use of source maps in the developers console. The console can be opened in Chrome by pressing cmd + option + i
or by going through the following menu options View -> Developer -> Developer Tools
. Once the console is open click on the gear, which is standardly located in the upper right hand side of the developers console. Inside settings there will be a General
section and under the Sources
sub-heading check off the Enable JavaScript source maps
if it is not already checked, as seen below.
The next thing to do is to compile the CoffeeScript into JavaScript and to also create the source map at the same time using the coffee-script
npm module. I accomplished this by using the following command, which I'll explain afterwards: coffee --watch --compile --map --output allAnagrams coffee/allAnagrams.coffee
. The --watch
flag tells the coffee module to watch for any changes in the directory I specify and to then recompile the JavaScript when changes are detected, that way I don't need to re-run this command each time I save the file. The --compile
flag compiles the CoffeeScript into JavaScript, while the --map
flag generates the source map. The final pieces of the command are where to output the compiled files and then where the CoffeeScript source files are located. The specific syntax is --output *destination* *source*
, where you would substitute in the appropriate destination and source folders.
Following this I then setup a basic HTML page to load my compiled JavaScript file, which references the source-map via a specific comment syntax of //# *source-map-location*
, substituting the relative path of the source map to the compiled JavaScript file. After these steps have been completed, the basic HTML page can be loaded and the CoffeeScript can be debugged in the console by adding breakpoints or debugger statements!
Project Source Code
Hopefully this should set you on your way towards using the powerful and incredibly useful ability of debugging your CoffeeScript files in the developers console. I've found it extremely handy after I got it figured out and set up. The source code for the little project I set up to demonstrate this is listed below, along with a couple of screen shots for the project layout and the command that I used to compile the CoffeeScript.
Project layout
index.html
<html>
<head>
<title></title>
<script src="scripts/fibonacci.js"></script>
</head>
<body>
<p>Tests!</p>
</body>
</html>
fibonacci.coffeescript
fibonacci = (n) ->
nums = [0, 1]
if n is 0 or n is 1 then return 1
counter = 1
while counter < n
temp = nums[1]
nums[1] = temp + nums[0]
nums[0] = temp
counter++
nums[1]
console.log(fibonacci(6))
fibonacci.js
// Generated by CoffeeScript 1.8.0
(function() {
var fibonacci;
fibonacci = function(n) {
var counter, nums, temp;
nums = [0, 1];
if (n === 0 || n === 1) {
return 1;
}
counter = 1;
while (counter < n) {
temp = nums[1];
nums[1] = temp + nums[0];
nums[0] = temp;
counter++;
}
return nums[1];
};
console.log(fibonacci(6));
}).call(this);
//# sourceMappingURL=fibonacci.js.map
fibonacci.js.map
{
"version": 3,
"file": "fibonacci.js",
"sourceRoot": "..",
"sources": [
"coffee/fibonacci.coffee"
],
"names": [],
"mappings": ";AAAA;AAAA,MAAA,SAAA;;AAAA,EAAA,SAAA,GAAY,SAAC,CAAD,GAAA;AACV,QAAA,mBAAA;AAAA,IAAA,IAAA,GAAO,CAAC,CAAD,EAAI,CAAJ,CAAP,CAAA;AACA,IAAA,IAAG,CAAA,KAAK,CAAL,IAAU,CAAA,KAAK,CAAlB;AAAyB,aAAO,CAAP,CAAzB;KADA;AAAA,IAEA,OAAA,GAAU,CAFV,CAAA;AAGA,WAAM,OAAA,GAAU,CAAhB,GAAA;AACE,MAAA,IAAA,GAAO,IAAK,CAAA,CAAA,CAAZ,CAAA;AAAA,MACA,IAAK,CAAA,CAAA,CAAL,GAAU,IAAA,GAAO,IAAK,CAAA,CAAA,CADtB,CAAA;AAAA,MAEA,IAAK,CAAA,CAAA,CAAL,GAAU,IAFV,CAAA;AAAA,MAGA,OAAA,EAHA,CADF;IAAA,CAHA;WASA,IAAK,CAAA,CAAA,EAVK;EAAA,CAAZ,CAAA;;AAAA,EAYA,OAAO,CAAC,GAAR,CAAY,SAAA,CAAU,CAAV,CAAZ,CAZA,CAAA;AAAA"
}