Thursday, April 2, 2015

An Article With Browserify Impressions

This is an opinionated article that discusses Browserify and compares it to RequireJS and Bower.

What is Browserify?

Browserify brings Node.js's require() function to client-side JavaScript. You can call require(...) to import npm packages, so Browserify solves two problems:
  1. Client-side package management (by using npm)
  2. Loading modules

Benefits of Using Browserify

Browserify has some 'magic' built-in that allows you to easily re-use most server-side code in your client-side code.

Because npm handles package management for Browserify, you can specify (most) of your client-side dependencies in your package.json along with your server-side dependencies. In my experience, having one place for dependencies really simplifies the process of adding a new dependency. Otherwise, you have to choose which package manager you want to use for packages that are available through multiple managers.


Problems With Alternatives

Like everything in JavaScript development, there are alternatives to Browserify. RequireJS can be used to load modules. For client-side package management, there's Bower. Either solution has problems that would be reduced or eliminated by using Browserify instead.

RequireJS requires using RequireJS modules or shims. Jam provides packages for RequireJS, but I found extremely out-of-date packages for popular libraries like Moment.js and Modernizr. For the most part, using RequireJS with popular client-side libraries means using shims. RequireJS shims can lead to a few minor problems as you either have to copy & paste JS files into your project or split dependencies into multiple specification files. Browserify shares this problem with RequireJS, but it's a smaller problem for reasons described below.

Bower has some problems of its own. I'll explain, but I must warn you ahead of time: friends and family of Bower should skip to 'Problems with Browserify.'

Bower is an incomplete package management solution. Every Bower package that I have ever installed dumps the complete contents of a Git repository into a directory. And there does not seem to be a standard for Bower package structure or documentation or use in client-side applications.

Every time I use a Bower package, I'm left wondering how to actually use the package in my code. I feel that this is a massive issue that prevents Bower from being as useful as it could be. npm and Browserify typically do not suffer from this problem for a few reasons:
  • npm packages almost always tell you how to start using the package
  • You typically don't need to know the structure of npm packages due to how they're used.
  • If you need to look in the node_modules folder, packages typically use a standard structure.

Problems With Browserify

Browersify is a full solution, but it comes with problems of its own.

It's unclear what npm package should be used for some client-side libraries. Modernizr has a few npm packages: browsernizrmodernizr, and browsernizr2. The first package is outdated, and the second package installs a tool that generates modernizr.js. I only found out about the third package as I was doing research for this article, and I don't know anything about it except its existence.

If a library doesn't have an easy-to-use npm package, you have to shim it with browserify-shim. This complicates inclusion of client-side vendor scripts in your project, and Browserify shares this issue with with RequireJS. Unlike RequireJS, this problem should be uncommon due to the availability of npm modules for popular client-side libraries.

Addendum: Comparison of Browserify and RequireJS

Browserify and RequireJS solve most of the same problems, so I figured that now would be a good time to give a quick rundown of differences and similarities.

Differences

Browserify loads npm modules.
RequireJS loads RequireJS modules.

Browserify always loads synchronously at compile/bundle time.
RequireJS loads asynchronously in the browser (but can be bundled using an optimizer).

Browserify always bundles scripts.
Bundling RequireJS apps requires a special optimizer.

Browserify uses npm.
RequireJS can be used with Jam, but you may be better off with using shims for third-party code.

Browserify allows you to access many Node.js functions and modules from client-side code.

RequireJS allows you to load non-JavaScript files (such as text files and Ember.js templates).

Similarities

Both load modules for client-side JavaScript.
Both have Grunt and Gulp plugins.

Sunday, August 24, 2014

RequireJS Impressions

RequireJS is a JavaScript library for defining and loading modules. It provides an alternative to including multiple <script> tags in your HTML in the right order and defining countless global variables (or properties for global variables.)

I've been using it quite a bit lately, so I have some opinions about it.

Good News

I like that RequireJS works with many browsers. The official site claims compatibility with ancient versions of every major browser. And have you seen its source code? A piece at the top checks to see if it's running on the Playstation 3's browser and does a little workaround just for it. I get the impression that RequireJS will work on anything that one would need it to, and that's a very good thing when you're building web sites that need to work everywhere.

"Ehhh..." News

Module names are case-sensitive. If you get the case wrong, RequireJS will happily reload modules. If those reloaded modules do anything to global state, you're heading for headache.

I could find only one bundling tool that properly bundles RequireJS modules together: the optimizer (r.js) that comes with RequireJS. This tool has "experimental support for source maps" (source: RequireJS Docs - Source Maps), so not using source maps poses two problems:
  1. Serving individual files for development and optimized files for production
  2. Actually using those files in each environment
Solving both of these problems can get tricky, especially in the ASP .NET MVC 4 environment that I've been working with. The easier of the two problems is the first: force the asset pipeline to use the output of r.js instead of its own optimized output. Easier said than done, but it's not impossible.

The second problem, actually using the files, is difficult and gets interesting when you're to use the application cache. One solution that I came up with is absolutely terrible and I will not be sharing it because it's wrong in so many ways. But I came up with it because there isn't much documentation available for taking full advantage of RequireJS's optimizer. Currently, it's a few sparse details and a (non-working) configuration file they put up on GitHub. This documentation could use some serious improvement.

These warts, while major, won't stop me from using RequireJS. It provides worthwhile functionality to client-side JavaScript. Browserify seems like a worthwhile replacement that fixes many of my RequireJS gripes, but I haven't used it yet and its compatibility is not as good as RequireJS's.

Saturday, July 12, 2014

jQuery Color & Body Background-Color WebKit Bug

jQuery Color is a nice jQuery plugin that allows you to animate color changes and much more. When testing a project that I was working on in Chrome (on Windows and Mac), I stumbled on a weird graphics glitch that occurs when animating a background color change for the entire page.

(Screenshot taken from latest Chrome for Windows)
See the light grey stripe at the bottom? It's supposed to be the same color as the rest of the page.

As far as I know, this is not a jQuery Color bug but rather a WebKit issue because it also affects Safari on Mac.

There are quite a few workarounds.

Fix #1 - Force redraw in animation done handler


The accepted answer is very simple; it's just three lines of JavaScript and doesn't require jQuery.

Using this fix with the entire body presented a problem with my project. These rapid changes to display make the page behave like it's scrolling back to the top.

Fix #2 - Apply two-thirds of clearfix to empty div/footer

My instincts told me to add an empty <footer /> to the bottom of the screen and give it clearfix styling. Clearfix corrects this bug. You can actually use two-thirds of a certain recommended clearfix:

footer:after {
    content:"";
    display: table;
}

(It's missing clear:both;)

<footer /> can be changed to <div /> or any number of other elements.

Fix #3 - Apply two-thirds of clearfix to body

Adding an empty HTML element seems like a bad idea to me. HTML5 is supposed to be about content, and here I am adding an element just to fix a browser-specific presentation bug.

As it turns out, you can use this bit of CSS and skip the empty footer:
body:after {
    content: "";
    display: table;
}

I don't know why this works

Maybe I'll update this post later when I figure it out.

Sunday, June 29, 2014

Using Git With TFS

Background (In a hurry? Skip this part.)

Did you know that Android Studio, as of this writing, does not have Team Foundation Server integration? This has a wide variety of consequences:
  • Every project file is read-only, and you need to unlock each manually
  • You cannot checkin files from Android Studio
  • New files are not automatically added to source control
  • Files that need to be excluded from source control might get checked-in
One way to avoid these problems is to use a different source control for Android Studio projects until it supports TFS. But you may be required to use TFS for any number of different reasons. For example, I work for a company that uses TFS for source control and work items.

There's a way to use Git (which Android Studio fully supports) with TFS repositories.

Use Git-TF

Git-TF allows you to use Git to manipulate TFS repositories. This is great for situations where you're not working from an IDE with TFS integration but still need to use TFS.

There are two ways of installing Git-TF: manually and with Chocolatey. Both are easy, but be careful about using the Chocolatey install because it requires JRE 7 (and not 8) and overwrites some system settings that you may need.

You'll want to follow Git-TF's "Individual developer with a new repository" instructions because you will want to work with a new Git repository on your local machine.

Recommendation: Checkin .gitignore to TFS

TFS does not use .gitignore files, but I think that they should still be checked into TFS. Multiple members of your team may want to use Git-TF for a project, and including .gitignore makes it easy for them to jump-in without having to add their own .gitignore.

Be Careful About Directories

If you currently use Git and TFS, using Git-TF should be easy. But there's a catch that I've encountered: Git-TF does not work well when used within a directory mapped to TFS.

If the TFS repository root is mapped to C:\TFS, and your Git repository is in C:\TFS\AndroidStudioProject, you will encounter errors when trying to checkin or shelve changes. These errors are workspace-related and (as far as I know) can only be resolved by unmapping the directory or creating your Git repository in a different directory (such as C:\GitProjects).

Sunday, April 20, 2014

Restrict Windows 8.1 'Everywhere' Search

Windows 8.1 (and Windows 8 before it) has a nifty feature: press Ctrl + Q to launch an 'everywhere' search. This makes it really easy to find files, open programs, and access system options. By default, the 'everywhere' search includes a few locations, including your entire user folder. This means that you will be searching through all music, videos, and documents on your computer.

That's usually a good thing. However, it can be very slow depending on the number of files. So you may want to turn this off for some directories.
  1. Find 'Indexing Options'. It's in the Control Panel, but it also shows-up in the Ctrl + Q 'everything' search.
  2. Click on 'Users' in 'Summary of selected locations'
  3. Locate and deselect whatever folders you don't want to look through

May 24, 2014 Update: Tweaked article contents. Added search description. Mention performance problems w/ searching through too many files.