Why?

I wanted to play with some newer stuff. So I decided to have a look at the “newest” contenders in the web dev playground.

What?

gulp the streaming task runner for node. Previously I used grunt and it is great. But there is one problem … it gets really slow with bigger projects. Especially in combination with sass/compass.

browserify allows you to use node.js-style requires in the browser and npm as the package manager. For me it is easier to use than require.js because of a much simpler configuration.

node-sass uses libSass to process sass/scss files into css. Because it is written in node.js and uses the c bindings it is much faster than the ruby sass executable.

Bourbon is a mixing library for sass which is much simpler and more lightweight than compass and has the most stuff I need.

React is a library for building user interfaces which uses a virtual DOM diff implementation for higher performance.

shoe is a library to use streams over sockjs. I used it to replace ajax requests. Just for fun …

Source code

You can find the source code on github.

Learnings

gulp is great. The one thing that makes it more useful than grunt to me is the configuration that is done in pure javascript. No obscure complex configuration object like in grunt. To define a task you just need to create code like this:

gulp.task(‘styles’, function () {

return gulp.src(‘./src/scss/main.scss’)

.pipe(sass({

outputStyle: gulp.env.production ? ‘compressed’ : ‘expanded’,

includePaths: [‘./src/scss’].concat(bourbon),

errLogToConsole: gulp.env.watch

}))

.pipe(gulp.dest(‘./dist/css’));

});

Because of the use of streams gulp seems to be much faster than grunt. The only downside I could see at this time is the lack of plugins. The grunt ecosystem is much bigger and more mature. You can find more on grunt vs gulp here.

browserify is awesome. Together with npm you get a nice package management system that just works without much configuration. The use of module.exports and require node.js style looks cleaner than the amd syntax of require.js. To get started you just need to have a package.json and a task in your gulpfile.js

“dependencies”: {

“react”: “~0.8.0",

“showdown”: “aslansky/showdown”,

“shoe”: “0.0.15"

} gulp.task(‘scripts’, function() {

return gulp.src(‘./src/js/app.js’, {read: false})

.pipe(browserify({

insertGlobals : false,

transform: [‘reactify’],

extensions: [‘.jsx’],

debug: !gulp.env.production

}))

.pipe(gulpif(gulp.env.production, uglify({

mangle: {

except: [‘require’, ‘export’, ‘$super’]

}

})))

.pipe(gulp.dest(‘./dist/js’));

});

After that you can start using require in your javascript.

var React = require(‘react’);

var CommentBox = require(‘./jsx/comment-box’);

or write modules with module.exports /** @jsx React.DOM */

‘use strict’; var React = require(‘react/addons’);

var Comment = require(‘./comment’);

var ReactTransitionGroup = React.addons.TransitionGroup; module.exports = React.createClass({

render: function() {

var cNodes = this.props.data.map(function (comment, i) {

return <Comment key={i} author={comment.author}>{comment.text}</Comment>;

});

return (

<ReactTransitionGroup transitionName=”comment”>

{cNodes}

</ReactTransitionGroup>

);

}

});

with node-sass and without the need for installing any ruby dependencies your project can stay in plain javascript. So no extra installations is needed. Also node-sass seems to process scss files much faster then ruby sass. The downside of node-sass is that not all mixins or mixin libraries are compatible. For example compass just doesn’t work.

Bourbon is a neat little mixin library for sass that is compatible with node-sass. It has all the features I need. In my view the documentation is better than compass’ and with Bourbon Neat it also has a great grid framework. Because Bourbon is plain scss there are no compatibility issues between versions like I had to experience with ruby sass and compass.

I chose to just play with React’s Tutorial implementation of a comment box. Usage of components makes the code really readable and JSX is a easy to understand syntax for templating. You don’t need to use JSX but it makes the source code of components even more understandable. For example the comment form looks like this:

/** @jsx React.DOM */

‘use strict’; var React = require(‘react’); module.exports = React.createClass({

handleSubmit: function() {

var author = this.refs.author.getDOMNode().value.trim();

var text = this.refs.text.getDOMNode().value.trim();

this.props.onCommentSubmit({author: author, text: text});

this.refs.author.getDOMNode().value = ‘’;

this.refs.text.getDOMNode().value = ‘’;

return false;

}, render: function() {

return (

<div className=”commentForm”>

<form className=”commentForm” onSubmit={this.handleSubmit}>

<input type=”text” placeholder=”Your name” ref=”author” />

<textarea placeholder=”Say something…” ref=”text”>

</textarea>

<button type=”submit”>Post</button>

</form>

</div>

);

}

});

Because I wanted to use Websockets instead of ajax with the react tutorial and all the new information I got about streams by using gulp, I decided to use shoe. The browser implementation is straight forward. Open a stream to the server and then wait for data to come in. If you want to send data to the server, just write to the stream.

var stream = shoe(‘/comments’);

this.stream.on(‘data’, function (data) {

this.setState({data: JSON.parse(data)});

});

this.stream.write(JSON.stringify(comment));

If you want to know more about the server side, have a look here. The shoe documentation also has some good examples.

Conclusion

First of all, it is fun to play with new things. You should try it sometimes. Second, the experience was great. All the libraries and tools work together nicely and I can imagine building a web application with this stack. The next thing I want to look into, is how to combine director with React to have a router for a single page site.