• Share
  • Share
Cross platform CoffeeScript and RequireJS

Cross platform CoffeeScript and RequireJS

Clearing the Coffeescript hurdles leads to developer insight

Dom DiCicco | October 19, 2015

If you’ve been a front end dev over the last few years then you’ve probably used or at least sampled CoffeeScript at some point. If you’ve used it for more than a brief moment of time, you probably hit quite a few roadblocks (just like you would with plain JS) and found yourself inspecting the compiled JavaScript. Regardless of your opinion of CoffeeScript, I think these roadblocks are great learning opportunities.

Here I was, ready to get my RequireJS (r.js) optimizer to start churning out some modularized-minified-production-ready client side code. Dreams of sub 500ms load times and just two JS files showing up in the dev tools network tab were abound. It all made sense. I had been writing modularized code using RequireJS, in CoffeeScript, that I could use in both the browser AND in my node.js server code. This was accomplished using amdefine. The missing piece between transitioning from dev environment JS to prod environment JS was the added step of using the r.js optimizer. So I threw together my build.js configuration file. An optimized layer was added for each real page’s root JavaScript module (the one you include in a script tag).

The build completes just fine. When loading the first page, I get a dreaded RequireJS error. “MISMATCHED ANONYMOUS DEFINE() MODULES”. It happens to be the first error on RequireJS ‘Common Errors’ page. I’ve seen that before when I was doing some tricky cross origin module loading. Basically, to look for the offending module, you just have to search through your optimized javascript for an anonymously defined module. They look like ‘define([…])’ instead of define(‘myModule’, […]). I found several of these in my built JavaScript. Everything looked fine on my build configuration and I couldn’t find anything in the source coffeescript files that looked tricky.

Eventually, I was able to find something in common with all of the files. They were all modules I was using cross platform, browser and node.js. The amdefine github page says to put the following at the top of your cross platform module.

When I was working that code into my project, I converted it to coffeescript as such:

I reread the mismatch error on the requirejs common errors page. ‘this will cause a problem for the optimizer because it avoids parsing files that declare a define variable’ caught my eye. I knew I wasn’t declaring a define variable, but I did rewrite JavaScript into CoffeeScript that had the define variable referenced in it. I then looked at the outputted coffeescript of each of these individual files and lo and behold, I had unknowingly declared define at the top of each of these files.

The only reason this potential cause is even listed on the error page is because this is common practice to avoid jslint/jshint errors for using globals that are naively reported as error.

Anyways, to fix the problem I just ended up embedding JavaScript into my CoffeeScript just for the amdefine snippet in each of the cross platform files. This is done using backticks.

I’d recommend someone new to JavaScript to give CoffeeScript a whirl to better understand the quirkiness of JavaScript…

  • “Why is CoffeeScript declaring all my variables ‘up top’?”
  • “What does the -> vs => translate to in JavaScript, and why?”
  • “JavaScript doesn’t have classes, what is this keyword hiding?”
All great questions which lead to rabbit holes of research, making you a better and more aware front end developer.

That all being said, as a seasoned JavaScript dev, I’ve ran into some issues with CoffeeScript that make me question the time saving aspect often proposed as an advantage of the language. This four hour debugging journey is the latest blow. It’s just another one of those things that pushes me further from CoffeeScript. It’s not that CoffeeScript did something wrong here. It’s just a CoffeeScript guard against bad JavaScript gone awry. It highlights the issue and time-suck of porting JavaScript to CoffeeScript, which at this point in time is inevitable given that JavaScript is what most reference material is written in (stackoverflow, previous projects, github, etc…).

Dom DiCicco

Dom DiCicco is a Cross Market solution architect based in Chicago. Dom is focused on implementing full-stack JavaScript solutions. Anyone that has worked with Dom knows he cares too much about css design patterns.