It’s been a long two weeks; one large project and several interviews have just eaten up tons of my time. I don’t really like traveling; it really wears me out.

I just wanted to write a tiny bit of CoffeeScript today. It’s a bit refreshing how much code you don’t have to write when you’re writing CoffeeScript. Nothing feels extraneous. All killer no filler, as they say. There are a couple good resources online for writing simple React stuff in CoffeeScript, but at least one of them is outdated, so I thought I’d rehash it.

hello, world!

A real crowd pleaser, this one. This is just to get you started. First, let’s create a basic directory structure to keep things separated. Written source code goes in src/ and generated source code goes in build/. Inside src/, code is separated into coffee/ (for CoffeeScript) and stylesheets/ (for SASS). I’m not going to write any styles today, but it’s good to have it in the build pipeline. Application/deliverable code goes in www/.

A skeleton structure

mkdir -p {build,src/{coffee,stylesheets},www}

.
├── [  68 Jun 29 17:47]  build/
├── [ 272 Jun 29 17:47]  src/
│   ├── [  68 Jun 29 17:47]  coffee/
│   └── [  68 Jun 29 17:47]  stylesheets/
└── [  68 Jun 29 17:47]  www/

Now let’s create our CoffeeScript & SASS source files, as well as our deliverable index.html.

touch src/coffee/app.coffee
touch src/stylesheets/style.sass
touch www/index.html

.
├── [  68 Jun 29 17:47]  build/
├── [ 340 Jun 29 17:47]  src/
│   ├── [ 102 Jun 29 17:49]  coffee/
│   │   └── [   0 Jun 29 17:52]  app.coffee
│   └── [ 102 Jun 29 17:49]  stylesheets/
│       └── [   0 Jun 29 17:52]  style.sass
└── [ 102 Jun 29 17:52]  www/
    └── [   0 Jun 29 17:52]  index.html

There’s a very good starter set of SASS files we’ll use: Bourbon, Neat, & Bitters. You’ll need to install these as Ruby Gems: gem install bourbon neat bitters. Also, we’ll install a common CSS reset: normalize.css.

(cd src/stylesheets; bourbon install)
(cd src/stylesheets; neat install)
(cd src/stylesheets; bitters install)
(cd www; wget http://necolas.github.io/normalize.css/latest/normalize.css)

The build pipeline

Now let’s start the build pipeline. This will generate deliverable JavaScript and CSS from our sources (which are still empty). You could set up a grunt/gulp/etc task to do this, but today I’ll just do it on the command line.

If you don’t have the CoffeeScript compiler installed, run a quick npm install -g coffee-script. You’ll also need to install Watchify to create your deployable Browserify bundle (npm install -g watchify), and any old HTTP server to view your work (npm install -g http-server).

First, run the CoffeeScript compiler to produce build/app.js.

coffee -o build/ -w -c src/coffee/* &

17:59:28 - compiled /.../src/coffee/app.coffee

Next, use that build/app.js to produce a Browserify bundle at www/bundle.js.

watchify -v -o www/bundle.js build/app.js &

564 bytes written to www/bundle.js (0.04 seconds)

Next, produce a CSS stylesheet at www/style.css.

sass --watch src/stylesheets/style.sass:www/style.css &

>>> Sass is watching for changes. Press Ctrl-C to stop.
      write www/style.css
      write www/style.css.map

Finally, start up an HTTP server to serve everything in www/.

http-server -p 8080 www/ &

Starting up http-server, serving www/ on: http://0.0.0.0:8080
Hit CTRL-C to stop the server

Fill in the blanks

Now that we’ve got a live build pipeline, we can open up http://localhost:8080/ and see our blank slate. Let’s fill in all three files.

www/index.html

<!DOCTYPE html>
<meta charset="utf-8">
<html>
  <head>
    <title>hello, world!</title>
    <link rel="stylesheet" type="text/css" href="normalize.css">
    <link rel="stylesheet" type="text/css" href="style.css">
  </head>
  <body>
    <script src="bundle.js"></script>
  </body>
</html>

src/stylesheets/style.sass

@import 'bourbon/bourbon'
@import 'neat/neat'
@import 'base/base'

src/coffee/app.coffee

React = require 'react'
{h3} = React.DOM

Message = React.createFactory React.createClass
  displayName: 'Message'
  render: ->
    h3 {}, "hello, #{@props.audience}!"

React.render Message(audience: 'world'), document.body

We’re not using any JSX here; it’s not exactly necessary given how nice CoffeeScript makes things. We pull the h3 function out of React.DOM, so instead of writing <h3>hello, {this.props.audience}</h3> we write h3 {}, "hello, #{@props.audience}". If you really miss JSX, you could probably find a compiler to work support writing that, but I’d rather not.

I create Message to just be a Factory that generates React Components; you could separate this into message = React.createClass .. and Message = React.createFactory message if you wanted to. If you’re ever confused what JavaScript we’re outputting, check build/app.js to see some very readable output. The displayName is something JSX will automatically set for debugging use; if you pop open the React tools in Chrome, that’s what fills in the <Message>..</Message> tag name.

Down below in the .render, we write Message(audience: 'world') instead of <Message audience="world" />. It’s the same thing, only different.

Finis

That’s it! Save all three files, watch the pipeline do its thing, and refresh your browser. This wasn’t supposed to be too complicated.