Category: Blog

How to switch to your project’s version of node when you cd into it.

If you’re using nvm to manage multiple versions of node.js, then you’ll want to automatically switch to the appropriate version of node for that project when you switch (cd) into it’s directory. The simplest, easiest, and most elegant way I’ve found so far is by adding the following lines into your .bash_profile or .bashrc:


# Method to check for existence of .nvmrc
# and switch versions if needed.
load-nvmrc() {
if [[ -f .nvmrc && -r .nvmrc ]]; then
nvm use
fi
}

# Override the cd command to load nvmrc
# whenever someone uses cd to switch into
# a directory
function cd () {
builtin cd "$@" && load-nvmrc;
}

Essentially we’re overriding the cd command to do some extra lifting. After adding the above code, you’ll want to reload / restart your terminal. Also, you’ll want to add an .nvmrc file to each project that uses a specific version of node. In the .nvmrc file, simply specify the version of node you’d like nvm to load when you cd into that project.

One of my project’s .nvmrc files looks like this:

4.4.5

How to fix Webpack when it can’t find your modules

If you are having problems with Webpack that produce the following errors:

Module not found: Error: Cannot resolve module 'some_module_name' in 'path/to/your_file'

Then, here are the steps to fixing it:
First, run Webpack with the ‘–display-error-details’ like so:
webpack --progress --color --watch --display-error-details
In my case, webpack is automatically run when I run npm run dev, so I had to make the change in my package.json file.

  • Now when you run Webpack, you’ll get a far clearer idea of what is actually wrong. Here are some possible issues / fixes:
    There may be a typo in your webpack.config – make sure everything looks right. Check it twice.
  • Your webpack.config could be missing a key detail / config. This was ultimately what was causing the error for me (details below).
  • If the module that Webpack is unable to find was written by you, make sure that the file names don’t have any trailing spaces. For example, it is very difficult to see the difference between ‘myfile.js’ and ‘myfile.js ‘. The latter has a space after it.
  • If Webpack is unable to find a third-party module such as react or redux, make sure that it is actually installed. Run npm install --save missing_module_name (replace ‘your_module_name with the actual module’s name) just to be sure.
  • As a last ditch Hare Krishna! / Hail Mary! / Hail Pasta!, you can try cleaning out and reinstalling your modules: npm cache clean && rm -rf ./node_modules && npm install.

My specific error and how I fixed it:

Whenever I ran npm run dev, I would get the following error trail:

ERROR in ./front/client/front_desk.jsx
Module not found: Error: Cannot resolve module 'react' in ...path_to/front_desk.jsx

but that wasn’t it, I was getting this for all 3rd party modules I was importing from even though they were installed correctly.

Finally, after some digging, I found that we could get more verbose errors out of Webpack by adding the –display-error-details flag. What’s awesome about this flag is that Webpack will list all the paths it used to find the missing module. In my case these were:

[../node_modules/react.js]
[../node_modules/react.jsx]
[../node_modules/react.js]
[../node_modules/react.jsx]
[../node_modules/react/index.js]
[../node_modules/react/index.jsx]
[../node_modules/react/react.js.js]
[../node_modules/react/react.js.jsx]

So, there was something wrong with how I was telling Webpack to resolve file extensions. I was using:
resolve: {
extensions: ['.js', '.jsx'],
},

when it should have been
resolve: {
extensions: ['', '.js', '.jsx'],
},

which, fixed the problem.

Firefox vs. Chrome SDKs

I wrote an extension for Firefox and Chrome. Here’s what happened:

TL;DR; The Chrome SDK felt simpler with clearer documentation. The Firefox’s developer community is incredibly helpful and their review process will make you a better programmer. You can’t go wrong with either one – but the Chrome SDK will get you there faster.

First Impressions:
I wrote the Firefox extension first because I use Firefox. I downloaded the SDK and followed the introductory tutorial. After the intro, there are some good tutorials on how to structure the extension and how to do specific tasks like detecting a webpage load. I then learned that there are high-level API calls and low-level API calls.

Feasibility Study:
While the high-level APIs are well-documented, many low-level APIs are marked as “unstable” or “deprecated”. This was unnerving when I found out that I needed to use an unstable API to achieve core functionality for my extension.

Eventually, with sufficient searching, asking questions on the Mozilla Developer IRC channels, and testing out code examples, I was able to get the basics working. There are some incredibly kind and gracious developers in the Mozilla developer network. I would not have gotten very far without their help.

Basic Functionality:
I needed to let users manage a list of websites, and update the plugin’s behavior whenever the list was saved. In Firefox, content modules don’t have direct access to storage. This means that instead of just saving the list whenever the user presses the Save button, we have to write some message-passing code to pass the list to the main module, which then saves it.

Plugin Options:
Firefox lets us create Preferences for extensions, which can be accessed by opening up the browser’s Add-ons window (Tools; Add-ons). The way to do this by specifying the preferences, their data-types, as well as some other basic info in the extensions’ manifest file. Then, in the extension’s main module, we can handle changes to the preferences through a listener. This means that Firefox stores and treats preferences separately from other data stored by the extension.

In my case, changing preferences also affected the content module, so this meant writing some more message-passing code. By the end though, the extension worked just as I’d wanted it to.

The Chrome SDK:
Once I released the Firefox version, many of my friends asked for a Chrome extension as well. I was pleasantly surprised that the Chrome SDK is more straight-forward. The Chrome extension, which has the exact same functionality as the Firefox extension resulted in less code, clearer and more consistent modules than my Firefox extension. Here’s what they did right:

  • Just one API: no separate High-level and low-level APIs. It felt clearer – in-fact, it was so good that I never had to turn to the chat-rooms for help.
  • One storage for all things: There is no special data storage for preferences. This means you only have to deal with one data-store for everything.
  • Open-ended Preferences: In Chrome, the preferences screen is free-form: just another HTML document. Put whatever you want in it, and save the user’s input directly into the extensions’ data store.
  • Consistency across modules: Since all modules have access to the data store, there is no need for special message passing code! This cleaned up my code by quite a bit and essentially standardized the basic structure of all modules.

Just like the Chrome section of this article, I had to write about half as much code for the Chrome extension, once I slogged through all the learning and writing of the Firefox extension :).

Rails 2.3 and options_for_select

I spent half a day on Tuesday trying to debug the following:

<%= f.select :number_of_items, options_for_select([1,2,3,4,5], @number_of_items), {}, {:class => "OrderField"} %>

Here, @number_of_items is the value of the same selection list, if for some reason the user had erroneously entered something in the rest of the form.

Turns out what happens is that the value is returned from the form and then assigned to @number_of_items is a string. Options_for_select throws an error because it is trying to create a selection list with integers as values, but is being told to set a string as the default value.

The form will keep loading up without the default value selected and you’ll waste hours wondering what’s wrong.

Solution: Do some type conversion like so:
<%= f.select :number_of_items, options_for_select([1,2,3,4,5], @number_of_items.to_i), {}, {:class => "OrderField"} %>

..Yup.

Some tricks to make JavaScript projects manageable

Most of the code in playr.me used to sit in one file – player.js. As I added the code for essential capabilities, the file began to grow. It finally got to the point where I often spent more time navigating the file than actually adding code. At the very least, I needed to break it up into multiple files.

But, what would be the best way to break things up into files? And how would I “include” those files into my project when JavaScript doesn’t have includes? Finally, how would communication work? Making calls across files means opening up multiple files later to track bugs across files!

Problem 1: How to include multiple files in a JavaScript project.
Solution: Use JavaScript to create a Script elements for each external file and add them to the document. Here’s how I did it for Playr.me.

Problem 2: Logical structure for dividing the files?
Solution: Divide the project up into modules. I read Anthony Colangelo’s“The Design of Code: Organizing JavaScript”, which is a great write-up on creating modules in JavaScript.

Problem 3: How will the modules communicate?
Of course, one can use ModuleName.methodName() to make method calls.
But there is a better way for certain situations: We can create JavaScript Events that each module can independently trigger and/or respond to!
I read How to Create Custom Events in JavaScript by Craig Buckler. Each playr.me module responds to a custom event called playrStatusChanged and then acts accordingly.

Making Youtube Fast

I attended a talk yesterday by the folks at YouTube about how they try to make a visitor’s experience as fast, or at least fast-feeling as possible. There was so much covered! Here’s what I still remember:

  • YouTube is a single-page app. All the JavaScript is loaded the first time we visit one of their pages. After that, the entire experience is managed using JavaScript callbacks. This saves a lot of bandwidth since the only thing that changes is content.
  • They do a lot of A/B testing on real users.
  • They’ve created a library to handle browser interactions back / forward / server callbacks / prioritizing the loading of on-screen objects… they love it.. they said they’ll open-source it soon! In the meantime.. roll your own.
  • They worry about the perception of speed and not just actual speed. The red loading bar on top of the new interface, for example, makes users feel that it’s running faster than it is.
  • Prioritize the loading of objects that are above the fold. Current JavaScript XHR lets you do this. Take advantage of it.
  • Request / send objects from the server in bunches, rather than all-at-once.
  • Try to stay mindful of when users expect certain items to work. For example, they probably expect the video to load first and keep playing while the other objects, thumbnails keep loading. So, start playing the video first and make sure it is sufficiently buffered before loading other things.

There was a bunch more discussed. Some of it was YouTube specific and some of it is currently beyond my understanding. The speakers were all really fantastic.

JavaScript’s function.apply() function..

As seen in A Re-Introduction To JavaScript

JavaScript functions are objects. So, when we declare a function, we get a bunch of other stuff for free! Take, the apply() method, which lets us pass an array into the arguments list of a method! I explain:

Say we have a function that calculates averages from a list of numbers passed into it:

function getAverage() {
  total = 0;
  for (i in arguments) {
    total += arguments[i];
  }
  return total / arguments.length;
}

We can now call this method to get the average of one or more numbers. Calling:
getAverage(4,2,3,5);
returns 3.5

We can also:
getAverage.apply(null, [4,2,3,5]);
which also returns 3.5!

Also, goes to show that functions are indeed Objects!

How to do fullscreen in JavaScript and CSS

I’ve been using the YouTube JavaScript Player API for a project. Something that I needed to figure out was how to create fullscreen controls for my custom video player. Here’s how:

Take the element (probably a div) to be full-screened, and full-screen it with the following JavaScript:

var c = document.getElementById('id_of_div_being_fullscreened'); 
// Browser specific fullscreening:
if (c.requestFullScreen) {
  c.requestFullScreen();
} else if (c.mozRequestFullScreen) {
  c.mozRequestFullScreen();
} else if (c.webkitRequestFullScreen) {
  c.webkitRequestFullScreen();
}

Now, what happens is fun. We can assign CSS properties to elements that are different in full-screen mode than regular mode. When in full-screen mode, the browser adds a class name of :-webkit-full-screen to full-screened elements. There’s probably one for Firefox called :-moz-full-screen, and one for other browsers called :-full-screen. How to use it:

  .MyPlayer:-webkit-full-screen {
    margin-top:0px;
    display:block;
    width:100%;
  }

  .MyPlayer:-webkit-full-screen .DefaultControls {
    z-index:2;
    display:block;
    top: 0px;
    position:absolute;
  }

As an aside: I noticed something while browsing through videos on Vimeo and YouTube: in this day of excellent HTML5 video, they still use Flash. Why? Because the Flash experience is the same across all browsers. When we try to full-screen a video, regardless of browser, the video instantly becomes full-screen, along with the controls, which behave appropriately. I bet the folks that worked on the Flash control don’t have to worry about detecting what browser the user is in.

Some things to remember when writing Chrome extensions (Part 2):

I recently built a chrome extension. It maps craigslist housing searches onto a map. This is a two part blog post on a few things I’ll keep in mind when writing more Chrome extensions. This is the second post and will talk about specifics about how different parts communicate with each other. Of course the official api reference probably does a better job, but this summary is as much for me as it is for you.

Message passing and organization:
This is the part that took the longest to understand because there a bunch of commands provided for sending messages between content scripts, background scripts, outside scripts, inside scripts, scripts that your grandma wrote and that doctor’s prescription for your hamster’s stress knee pain.

So here’s how I did it. Two parts to each message – sending, and receiving:
From a content script to a background script:
In the background.js, the following umbrella method:

"chrome.extension.onRequest.addListener"

.
In the content.js, the following single call:

chrome.extension.sendRequest('data', function (response) {/* do stuff if needed */});

From the background script to content:
In the background.js, a single call with:

chrome.tabs.sendMessage(tab.id, {message: 'addAdToMap', data: this.adData}, function() {/* do stuff if needed */});

The following umbrella method to handle them all in the content.js:

chrome.extension.onMessage.addListener( function(request, sender, response)

From content scripts to iframes that live inside the content
Whoa. Doube-you Tee Eff, mate. Why would you do this? Why, I’m glad you asked: The reason you’d want to is because Chrome is a bully that protects you from bullies. Seriously this made me refactor my whole extension.
From the content window to the iframe:
In the content.js:

mapAway = function(location, data) {  
  var iframe = document.getElementById('mapFrame');
  var message = {
    command: 'mapMe',
    mapData: {
      mapLocation: location,
      mapData: data
    }
  };
  iframe.contentWindow.postMessage(message, '*');
}

In the iframe’s js, the following umbrella method:

window.addEventListener("message", function(event) {

From iframe to content scripts the following:
In the iframe.js:

  var message = {
    command: 'ready'
  }
  window.parent.postMessage(message, '*');

In the content.js the following umbrella method:

window.addEventListener("message", function(event) {

More to come as I think. I almost feel like this post is therapy for me and help for you. And help for me the next time I write an extension. Also, here’s the code to my extension. It makes use of all the different types of message passing described above. So, I hope it helps!

Some things to remember when writing Chrome extensions (Part 1):

I recently built a chrome extension. It maps craigslist housing searches onto a map. This is a two part blog post on a few things I’ll keep in mind when writing more Chrome extensions. This is the first post and will talk about parts of a chrome extension and where to put code. Of course the official documentation probably does a better job, but this summary is as much for me as it is for you.

Each Chrome extension has the following files:
manifest.js: This file will contain basic but important information about the extension, such as it’s name, description, any files being included, websites when the extension will come alive, as well as be able to make cross-site requests, as well as security considerations.
background.js: This file is your grand daddy. It orchestrates communication between the different parts of the system.
Other JavaScript files: These files represent what will happen inside different content views – page actions, browser actions, tabs etc.

Code organization:
background.js – Anything that the browser does, such as opening new tabs, placing buttons, assigning action to a browser button and so on, is handled by background.js.
some_content_script.js – You guessed it! Things that happen inside the content of a window – basically whatever happens inside the html tags is handled by some content js.

1 2