Code Like Node In Your Browser With Browserify

I've written about how to make an extremely simple web app with express and pug templates, but where's the interactivity?

I don't know about you, but I'm not into web development to make static websites. I want to make applications!

It's finally time to start writing JavaScript in the browser.

Let's start by making a simple express app. Here's index.js:

var express = require('express')  
var app = express()  
app.use(express.static('public'))  
app.set('view engine', 'pug')

app.get('/', function (req, res) {  
    res.render('index')
})

app.listen(3000, function () {  
    console.log('Example app listening on port 3000!')
})

And here's views/index.pug:

html  
    head
        title code like node
    body
        h1 code like node
    script(src='js/main.js')

You'll see at the bottom that I've added a script tag and set its source path to js/main.js. In index.js I've set our public folder to public so we'll need to create a public/js folder and stick a main.js in there.

Here's main.js:

console.log('hey!')  

If you run this app, you'll get a page with the content and title of "code like node". But where's the "hey!"?

If you're in Chrome, Firefox, or Safari*, right-click on the page and choose "inspect", then click on the "console" tab that appears. You should see our console.log message.

*(Dunno how to do it in I.E., you microsofties are on your own. :) )

This is great and all, but what if I want to use a library like ramda? Go ahead and create a node_modules directory in public/js, navigate to public/js and run an npm install ramda.

When npm installs something it will look for a node_modules directory to put stuff in before it creates that directory.

Since we've put a node_modules folder in public/js, npm will put ramda in that folder instead of the node_modules in the root of the project.

You'd think that all you'd have to do to start using ramda would be to modify main.js like so:

var R = require('ramda')

console.log('hey!')  

But if you run this you'll get an error message:

main.js:1 Uncaught ReferenceError: require is not defined  

In the browser, there is no such thing as modules!!

Before developers started coming up with their own solutions, the only option was to add another script tag:

html  
    head
        title code like node
    body
        h1 code like node
    script(src='js/node_modules/ramda/dist/ramda.js')
    script(src='js/main.js')

As you can imagine, this can become a pain in the neck pretty fast. Thankfully the modern JavaScript community has given us alternatives. My current fave is Browserify.

Let's do an npm install browserify (in the root directory, not in public/js)and create another directory called front-end.

Let's also make a front-end/js directory and create another main.js in front-end/js.

We'll also move the node_modules directory to front-end/js by running mv public/js/node_modules/ front-end/js/.

Ok, let's open up front-end/js/main.js edit it like so:

var R = require('ramda')

console.log(  
    R.map(function (x) { return 2 * x }, [1, 2, 3]))

and (from the root of the project) run the following command:

browserify front-end/js/main.js -o public/js/main.js  

front-end/js/main.js is our source file, -o tells browserify to bundle the result, and public/js/main.js is our destination, the name of our bundled file. If our source file requires any other modules, browserify will include them in the destination file.

Pretty sweet huh? Now you can do modules in the browser just like you do in Node.

But what if I do the following?

var R = require('ramda')

console.log(  
    R.map(x => 2 * x, [1, 2, 3]))

If I run that bit of code in the browser it ---

wait, what?

It works?

Ok, that's weird. I thought I'd have to introduce Babel to y'all, but apparently I don't? It looks like browswerify will compile your source code to ES2015 (the latest version of JavaScript) without any further plugins.

Weird. Well, that takes away a dependency I won't use again. Bye bye babel. :P

Ok, write at y'all later! :)

--- Edit ---
Nope! Nope! Nope!

I couldn't be wrong if my name were Sir Wrongy Wronginstein of the I'm Not Correct Brigade.

That's not it at all. You still gotta use Babel or something similar. :)

I'll write about why I thought this very wrong and incorrect thing next time. In the mean time, enjoy Node-like modules in the browser.

Looking for a software developer?