Source Maps – Debug your Bundled, Minified Code

While developing a web app, it’s a good idea to bundle all your various JavaScript files and libraries into a single, minified file for production. Bundling makes your app faster by reducing download size and saving the browser from having to perform multitudes of HTTP requests just to render the page.

However, bundling comes at a cost. Debugging bundled JavaScript is often a nightmare. If your app has an error, the error in the console points at the point in the bundle file where the code failed, which may or may not bear any resemblance to your actual project files.

Which would you rather debug?

Which would you rather debug?

Wouldn’t it be great if the debugger was smart enough to point you at your original, pre-bundled code instead? Enter source maps, a way to preserve reference to your original file and code structure, even through bundling.

Before We Begin

This article uses the following tools, so make sure you have them first (or at least the basic concepts about them):

(PS: Grunt and Browserify can do source maps, too.)

How Source Maps Work

A source map is a composed of data that links pieces of your minified bundle back to the original, unbuilt files. Modern dev tools will automatically follow the map for any console.log or line queries you perform.

Showing The Problem

Let’s say I have a simple console.log in an angularjs controller someplace:

angular.module('myApp')
  .controller('CtrlMain', function ($scope) {
    console.log('hello');
  });

When we run the app and look in Chrome’s JavaScript console, it provides a very unhelpful link to where the log was executed:
Screenshot from 2014-11-27 17:07:20Oh, it’s in the one and only line in my bundled script? I never would have guessed.

To generate bundle.js, I’m using the following task in Gulp:

gulp.task('build-js', function () {
  gulp.src([jsDir + 'module.js',jsDir + '*.js'])
    .pipe(concat('bundle.js'))
    .pipe(ngAnnotate())
    .pipe(uglify())
    .pipe(gulp.dest('build'));
});

This concatenates all JavaScript files into a single file called bundle.js, creates dependency injection annotations so Angular doesn’t choke on the minified code, minifies the code using gulp-uglify, and finally writes it to a build directory.

Adding Source Maps To The Build Process

Here’s how to add source map creation to this build process, using gulp-sourcemaps:

gulp.task('build-js', function () {
  gulp.src([jsDir + 'module.js',jsDir + '*.js'])
    .pipe(sourcemaps.init())
    .pipe(concat('bundle.js'))
    .pipe(ngAnnotate())
    .pipe(uglify())
    .pipe(sourcemaps.write())
    .pipe(gulp.dest('build'));
});

Before we do anything to the JavaScript files, we call sourcemaps.init(). This tells gulp-sourcemaps to pay attention and generate our source maps while the build process occurs. sourcemaps.write() signals that we’re done processing the .js files and ready to write out the bundled file.

IMPORTANT NOTE: All plugins used between sourcemaps.init() and sourcemaps.write() must be supported specifically by gulp-sourcemaps. You can find a list of supported plugins here.

The Final Product

Now let’s build and run the app again and see what we get:

Screenshot from 2014-11-27 18:19:39

Much better

Now the console.log behaves as if we’re working with the clear, unbuilt versions of our files. We can click that link on the left to see exactly which line contains the log. Ahhhh.

 

7 IntelliJ IDEA tips and settings you’ll probably love

Hardly a week goes by where I don’t learn something new about IntelliJ! Here are just a few of my favorite IntelliJ settings tweaks and workflow tips.

This article was written for IntelliJ IDEA 14 professional and community editions.

1. Exclude some folders from search

If searching in your project is returning a lot of non-project files you’d rather not see (such as files in /node_modules, /tmp, or /build), you can permanently exclude those files.

Go to File > Project Structure > Project Settings > Modules. Right click any folders you don’t want to ever search in and mark them as Excluded. Done!

exclude_folders_from_search_intellij_idea

2. Highlight current file in project hierarchy

Do you want to see where your currently active file is in the project structure? Of course you do. Turn on “Autoscroll from Source” by clicking the little gear in the little toolbar at the top of the project structure window.

Now whatever file you’re editing will be automatically highlighted in the project structure pane.

highlight_file_in_hierarchy

3. Start a local server with a single click

For all your little web projects that you want to test in browser without bothering to set up a server first, just right click the file you want to serve and choose Open in Browser.

local_server_intellij_right_click_file

I overlooked this feature in the past because I thought it was just going to open the file all vanilla and stuff, but it totally starts a little standalone server! 

intellij_temp_server

4. Resolve git conflicts

IntelliJ IDEA’s git merge conflict resolution tool is fun and convenient. Just right click in any of your project’s files (doesn’t have to be the one with the conflict in it) and go to Git > Resolve Conflicts…

right_click_resolve_git_merge

You’ll get a modal with a list of all the files containing conflicts. Choose Merge…

files_with_conflicts_git_merge_intellij

In this screen, you can compare your changes (on the left) to what you got from the server when you pulled (on the right) and view the result (in the middle). Move changes to the result by clicking on the >> and << symbols, and reject changes by clicking the X. You can even edit the final version manually right there in the middle pane.

intellij_merge_conflict_tool

5. Search EVERYWHERE

You know you’ve seen it… somewhere. But your project is huge and that file could be anywhere. Double-tap the Shift key to open up Search everywhere. I use this shortcut to hop between files all the time because it’s just so convenient.

6. GitHub integration

In the right click menu (click inside a file or on a file in the project hierarchy) there are a couple shortcuts to GitHub. Open on GitHub is handy for jumping right to the file you’re working on to view its history, Create Gist is handy if you like making Gists.

create_gist_from_intelliJ

7. Turn on Annotations to know who to blame (it was probably you)

Who wrote this line of code? Now you can know: right click in the left margin (where the line numbers are) and turn on Annotate.

annotate_intellij

Hovering your cursor over individual lines reveals the last commit message, too.

git_annotate_names

There you have it: a short ‘n sweet guide to 7 helpful IntelliJ tools, shortcuts, and settings.

Push to GitHub without entering username and password every time (Git Bash on Windows)

Today I learned… how to save my GitHub username and password so I don’t have to re-enter them every time I push something to GitHub from my Windows machine.

A bit of backstory:

I recently set up git on my Windows 7 machine using Git for Windows (mysisgit). That process went smoothly and I feel right at home in my little emulator, Git Bash, using all the same commands I already know and love from my Mac.

If you’re used to using git on a Mac and have to work on a Windows machine for whatever reason, I highly recommend mysisgit.

Credential check… every time!

Everything was going great until I pushed my changes. Every push triggered a new credentials check!

$ git push origin master
Username for 'https://github.com': xyz
Password for 'https://xyz@github.com':

I don’t want to enter my GitHub username and password every time I push something.

HTTPS vs. SSH?

So I hit the Google and found this StackOverflow question, where some helpful folks say the problem results from connecting over HTTPS instead of SSH, but GitHub’s help documentation recommends connecting over HTTPS, not SSH.

I’m hesitant to disobey the word of GitHub, so instead of relying on SSH, I followed GitHub’s instructions to use a credentials helper.

Credentials Helper Setup

However… GitHub’s explanation of how to cache your password with the credentials helper aren’t very clear. They tell you to enter this line and then don’t tell you what to do next.

Here’s what I did – worked for me.

In your Git Bash window, enter this line:

$ git config --global credential.helper wincred

Now push a change to Github and enter your credentials – this is where your username and password information gets saved to the credential helper.

You won’t get any feedback telling you that, but you can confirm it worked by pushing another change. This time, you shouldn’t have to enter your credentials again.

But I have this problem on Linux!

Try this: Caching your GitHub password in Git

$ git config --global credential.helper cache


Automate Express server restarts with Nodemon

Today I learned… that you don’t have to navigate to Terminal, press CTRL + C to stop the server, and re-enter node server.js to start up the express server again in order to see your latest work in the browser.

There’s a better way: get Nodemon and automate this repetitive process!

Nodemon will watch the files in the directory you run it in and restart your server automatically when it detects a change.

To install Nodemon:

$ npm -g install nodemon

To get Nodemon running:

$ nodemon server.js

Leave that Terminal window open and let Nodemon work its magic.