In this article by Alex Libby, author of the book Mastering jQuery, we will examine some of the options available to help develop your skills even further.
(For more resources related to this topic, see here.)
Local or CDN, I wonder…? Which version…? Do I support old IE…?
Installing jQuery is a thankless task that has to be done countless times by any developer—it is easy to imagine that person asking some of the questions. It is easy to imagine why most people go with the option of using a Content Delivery Network (CDN) link, but there is more to installing jQuery than taking the easy route!
There are more options available, where we can be really specific about what we need to use—throughout this article, we will. We’ll cover a number of topics, which include:
- Downloading and installing jQuery
- Customizing jQuery downloads
- Building from Git
- Using other sources to install jQuery
- Adding source map support
- Working with Modernizr as a fallback
Intrigued? Let’s get started.
Downloading and installing jQuery
As with all projects that require the use of jQuery, we must start somewhere—no doubt you’ve downloaded and installed jQuery a thousand times; let’s just quickly recap to bring ourselves up to speed.
If we browse to http://www.jquery.com/download, we can download jQuery using one of the two methods: downloading the compressed production version or the uncompressed development version. If we don’t need to support old IE (IE6, 7, and 8), then we can choose the 2.x branch. If, however, you still have some diehards who can’t (or don’t want to) upgrade, then the 1.x branch must be used instead.
To include jQuery, we just need to add this link to our page:
<script src="http://code.jquery.com/jquery-X.X.X.js"></script>
Here, X.X.X marks the version number of jQuery or the Migrate plugin that is being used in the page.
Conventional wisdom states that the jQuery plugin (and this includes the Migrate plugin too) should be added to the <head> tag, although there are valid arguments to add it as the last statement before the closing <body> tag; placing it here may help speed up loading times to your site.
This argument is not set in stone; there may be instances where placing it in the <head> tag is necessary and this choice should be left to the developer’s requirements. My personal preference is to place it in the <head> tag as it provides a clean separation of the script (and the CSS) code from the main markup in the body of the page, particularly on lighter sites.
I have even seen some developers argue that there is little perceived difference if jQuery is added at the top, rather than at the bottom; some systems, such as WordPress, include jQuery in the <head> section too, so either will work. The key here though is if you are perceiving slowness, then move your scripts to just before the <body> tag, which is considered a better practice.
Using jQuery in a development capacity
A useful point to note at this stage is that best practice recommends that CDN links should not be used within a development capacity; instead, the uncompressed files should be downloaded and referenced locally. Once the site is complete and is ready to be uploaded, then CDN links can be used.
Adding the jQuery Migrate plugin
If you’ve used any version of jQuery prior to 1.9, then it is worth adding the jQuery Migrate plugin to your pages. The jQuery Core team made some significant changes to jQuery from this version; the Migrate plugin will temporarily restore the functionality until such time that the old code can be updated or replaced.
The plugin adds three properties and a method to the jQuery object, which we can use to control its behavior:
Property or Method |
Comments |
jQuery.migrateWarnings |
This is an array of string warning messages that have been generated by the code on the page, in the order in which they were generated. Messages appear in the array only once even if the condition has occurred multiple times, unless jQuery.migrateReset() is called. |
jQuery.migrateMute |
Set this property to true in order to prevent console warnings from being generated in the debugging version. If this property is set, the jQuery.migrateWarnings array is still maintained, which allows programmatic inspection without console output. |
jQuery.migrateTrace |
Set this property to false if you want warnings but don’t want traces to appear on the console. |
jQuery.migrateReset() |
This method clears the jQuery.migrateWarnings array and “forgets” the list of messages that have been seen already. |
Adding the plugin is equally simple—all you need to do is add a link similar to this, where X represents the version number of the plugin that is used:
<script src="http://code.jquery.com/jquery-migrate- X.X.X.js"></script>
If you want to learn more about the plugin and obtain the source code, then it is available for download from https://github.com/jquery/jquery-migrate.
Using a CDN
We can equally use a CDN link to provide our jQuery library—the principal link is provided by MaxCDN for the jQuery team, with the current version available at http://code.jquery.com. We can, of course, use CDN links from some alternative sources, if preferred—a reminder of these is as follows:
- Google (https://developers.google.com/speed/libraries/devguide#jquery)
- Microsoft (http://www.asp.net/ajaxlibrary/cdn.ashx#jQuery_Releases_on_the_CDN_0)
- CDNJS (http://cdnjs.com/libraries/jquery/)
- jsDelivr (http://www.jsdelivr.com/#%!jquery)
Don’t forget though that if you need, we can always save a copy of the file provided on CDN locally and reference this instead. The jQuery CDN will always have the latest version, although it may take a couple of days for updates to appear via the other links.
Using other sources to install jQuery
Right. Okay, let’s move on and develop some code! “What’s next?” I hear you ask.
Aha! If you thought downloading and installing jQuery from the main site was the only way to do this, then you are wrong! After all, this is about mastering jQuery, so you didn’t think I will only talk about something that I am sure you are already familiar with, right?
Yes, there are more options available to us to install jQuery than simply using the CDN or main download page. Let’s begin by taking a look at using Node.
Each demo is based on Windows, as this is the author’s preferred platform; alternatives are given, where possible, for other platforms.
Using Node JS to install jQuery
So far, we’ve seen how to download and reference jQuery, which is to use the download from the main jQuery site or via a CDN. The downside of this method is the manual work required to keep our versions of jQuery up to date! Instead, we can use a package manager to help manage our assets. Node.js is one such system. Let’s take a look at the steps that need to be performed in order to get jQuery installed:
- We first need to install Node.js—head over to http://www.nodejs.org in order to download the package for your chosen platform; accept all the defaults when working through the wizard (for Mac and PC).
- Next, fire up a Node Command Prompt and then change to your project folder.
- In the prompt, enter this command:
npm install jquery
- Node will fetch and install jQuery—it displays a confirmation message when the installation is complete:
- You can then reference jQuery by using this link:
<name of drive>:websitenode_modulesjquerydistjquery.min.js.
Node is now installed and ready for use—although we’ve installed it in a folder locally, in reality, we will most likely install it within a subfolder of our local web server. For example, if we’re running WampServer, we can install it, then copy it into the /wamp/www/js folder, and reference it using http://localhost/js/jquery.min.js.
If you want to take a look at the source of the jQuery Node Package Manager (NPM) package, then check out https://www.npmjs.org/package/jquery.
Using Node to install jQuery makes our work simpler, but at a cost. Node.js (and its package manager, NPM) is primarily aimed at installing and managing JavaScript components and expects packages to follow the CommonJS standard. The downside of this is that there is no scope to manage any of the other assets that are often used within websites, such as fonts, images, CSS files, or even HTML pages.
“Why will this be an issue?,” I hear you ask. Simple, why make life hard for ourselves when we can manage all of these assets automatically and still use Node?
Installing jQuery using Bower
A relatively new addition to the library is the support for installation using Bower—based on Node, it’s a package manager that takes care of the fetching and installing of packages from over the Internet. It is designed to be far more flexible about managing the handling of multiple types of assets (such as images, fonts, and CSS files) and does not interfere with how these components are used within a page (unlike Node).
For the purpose of this demo, I will assume that you have already installed it; if not, you will need to revisit it before continuing with the following steps:
- Bring up the Node Command Prompt, change to the drive where you want to install jQuery, and enter this command:
bower install jquery
This will download and install the script, displaying the confirmation of the version installed when it has completed.
The library is installed in the bower_components folder on your PC. It will look similar to this example, where I’ve navigated to the jquery subfolder underneath.
By default, Bower will install jQuery in its bower_components folder. Within bower_components/jquery/dist/, we will find an uncompressed version, compressed release, and source map file. We can then reference jQuery in our script using this line:
<script src="/bower_components/jquery/jquery.js"></script>
We can take this further though. If we don’t want to install the extra files that come with a Bower installation by default, we can simply enter this in a Command Prompt instead to just install the minified version 2.1 of jQuery:
bower install http://code.jquery.com/jquery-2.1.0.min.js
Now, we can be really clever at this point; as Bower uses Node’s JSON files to control what should be installed, we can use this to be really selective and set Bower to install additional components at the same time. Let’s take a look and see how this will work—in the following example, we’ll use Bower to install jQuery 2.1 and 1.10 (the latter to provide support for IE6-8).
- In the Node Command Prompt, enter the following command:
bower init
This will prompt you for answers to a series of questions, at which point you can either fill out information or press Enter to accept the defaults.
- Look in the project folder; you should find a bower.json file within. Open it in your favorite text editor and then alter the code as shown here:
{
"ignore": [ "**/.*", "node_modules", "bower_components",
"test", "tests" ] ,
"dependencies": {
"jquery-legacy": "jquery#1.11.1",
"jquery-modern": "jquery#2.10"
}
}
At this point, you have a bower.json file that is ready for use. Bower is built on top of Git, so in order to install jQuery using your file, you will normally need to publish it to the Bower repository.
Instead, you can install an additional Bower package, which will allow you to install your custom package without the need to publish it to the Bower repository:
- In the Node Command Prompt window, enter the following at the prompt:
npm install -g bower-installer
- When the installation is complete, change to your project folder and then enter this command line:
bower-installer
- The bower-installer command will now download and install both the versions of jQuery.
At this stage, you now have jQuery installed using Bower. You’re free to upgrade or remove jQuery using the normal Bower process at some point in the future.
If you want to learn more about how to use Bower, there are plenty of references online; https://www.openshift.com/blogs/day-1-bower-manage-your-client-side-dependencies is a good example of a tutorial that will help you get accustomed to using Bower. In addition, there is a useful article that discusses both Bower and Node, available at http://tech.pro/tutorial/1190/package-managers-an-introductory-guide-for-the-uninitiated-front-end-developer.
Bower isn’t the only way to install jQuery though—while we can use it to install multiple versions of jQuery, for example, we’re still limited to installing the entire jQuery library.
We can improve on this by referencing only the elements we need within the library. Thanks to some extensive work undertaken by the jQuery Core team, we can use the Asynchronous Module Definition (AMD) approach to reference only those modules that are needed within our website or online application.
Using the AMD approach to load jQuery
In most instances, when using jQuery, developers are likely to simply include a reference to the main library in their code. There is nothing wrong with it per se, but it loads a lot of extra code that is surplus to our requirements.
A more efficient method, although one that takes a little effort in getting used to, is to use the AMD approach. In a nutshell, the jQuery team has made the library more modular; this allows you to use a loader such as require.js to load individual modules when needed.
It’s not suitable for every approach, particularly if you are a heavy user of different parts of the library. However, for those instances where you only need a limited number of modules, then this is a perfect route to take. Let’s work through a simple example to see what it looks like in practice.
Before we start, we need one additional item—the code uses the Fira Sans regular custom font, which is available from Font Squirrel at http://www.fontsquirrel.com/fonts/fira-sans.
Let’s make a start using the following steps:
- The Fira Sans font doesn’t come with a web format by default, so we need to convert the font to use the web font format. Go ahead and upload the FiraSans-Regular.otf file to Font Squirrel’s web font generator at http://www.fontsquirrel.com/tools/webfont-generator. When prompted, save the converted file to your project folder in a subfolder called fonts.
- We need to install jQuery and RequireJS into our project folder, so fire up a Node.js Command Prompt and change to the project folder.
- Next, enter these commands one by one, pressing Enter after each:
bower install jquery
bower install requirejs - We need to extract a copy of the amd.html and amd.css files—it contains some simple markup along with a link to require.js; the amd.css file contains some basic styling that we will use in our demo.
- We now need to add in this code block, immediately below the link for require.js—this handles the calls to jQuery and RequireJS, where we’re calling in both jQuery and Sizzle, the selector engine for jQuery:
<script>
require.config({
paths: {
"jquery": "bower_components/jquery/src",
"sizzle": "bower_components/jquery/src/sizzle/dist/sizzle"
}
});
require(["js/app"]);
</script> - Now that jQuery has been defined, we need to call in the relevant modules. In a new file, go ahead and add the following code, saving it as app.js in a subfolder marked js within our project folder:
define(["jquery/core/init", "jquery/attributes/classes"],
function($) {
$("div").addClass("decoration");
});We used app.js as the filename to tie in with the require([“js/app”]); reference in the code.
- If all went well, when previewing the results of our work in a browser.
Although we’ve only worked with a simple example here, it’s enough to demonstrate how easy it is to only call those modules we need to use in our code rather than call the entire jQuery library. True, we still have to provide a link to the library, but this is only to tell our code where to find it; our module code weighs in at 29 KB (10 KB when gzipped), against 242 KB for the uncompressed version of the full library!
Now, there may be instances where simply referencing modules using this method isn’t the right approach; this may apply if you need to reference lots of different modules regularly.
A better alternative is to build a custom version of the jQuery library that only contains the modules that we need to use and the rest are removed during build. It’s a little more involved but worth the effort—let’s take a look at what is involved in the process.
Customizing the downloads of jQuery from Git
If we feel so inclined, we can really push the boat out and build a custom version of jQuery using the JavaScript task runner, Grunt. The process is relatively straightforward but involves a few steps; it will certainly help if you have some prior familiarity with Git!
The demo assumes that you have already installed Node.js—if you haven’t, then you will need to do this first before continuing with the exercise.
Okay, let’s make a start by performing the following steps:
- You first need to install Grunt if it isn’t already present on your system—bring up the Node.js Command Prompt and enter this command:
npm install -g grunt-cli
- Next, install Git—for this, browse to http://msysgit.github.io/ in order to download the package.
- Double-click on the setup file to launch the wizard, accepting all the defaults is sufficient for our needs.
If you want more information on how to install Git, head over and take a look at https://github.com/msysgit/msysgit/wiki/InstallMSysGit for more details.
- Once Git is installed, change to the jquery folder from within the Command Prompt and enter this command to download and install the dependencies needed to build jQuery:
npm install
- The final stage of the build process is to build the library into the file we all know and love; from the same Command Prompt, enter this command:
grunt
- Browse to the jquery folder—within this will be a folder called dist, which contains our custom build of jQuery, ready for use.
If there are modules within the library that we don’t need, we can run a custom build. We can set the Grunt task to remove these when building the library, leaving in those that are needed for our project.
For a complete list of all the modules that we can exclude, see https://github.com/jquery/jquery#modules.
For example, to remove AJAX support from our build, we can run this command in place of step 5, as shown previously:
grunt custom:-ajax
This results in a file saving on the original raw version of 30 KB as shown in the following screenshot:
The JavaScript and map files can now be incorporated into our projects in the usual way.
For a detailed tutorial on the build process, this article by Dan Wellman is worth a read (https://www.packtpub.com/books/content/building-custom-version-jquery).
Using a GUI as an alternative
There is an online GUI available, which performs much the same tasks, without the need to install Git or Grunt. It’s available at hhttp://projects.jga.me/jquery-builder/, although it is worth noting that it hasn’t been updated for a while!
Okay, so we have jQuery installed; let’s take a look at one more useful function that will help in the event of debugging errors in our code. Support for source maps has been made available within jQuery since version 1.9. Let’s take a look at how they work and see a simple example in action.
Adding source map support
Imagine a scenario, if you will, where you’ve created a killer site, which is running well, until you start getting complaints about problems with some of the jQuery-based functionality that is used on the site. Sounds familiar?
Using an uncompressed version of jQuery on a production site is not an option; instead we can use source maps. Simply put, these map a compressed version of jQuery against the relevant line in the original source.
Historically, source maps have given developers a lot of heartache when implementing, to the extent that the jQuery Team had to revert to disabling the automatic use of maps!
For best effects, it is recommended that you use a local web server, such as WAMP (PC) or MAMP (Mac), to view this demo and that you use Chrome as your browser.
Source maps are not difficult to implement; let’s run through how you can implement them:
- Extract a copy of the sourcemap folder and save it to your project area locally.
- Press Ctrl + Shift + I to bring up the Developer Tools in Chrome.
- Click on Sources, then double-click on the sourcemap.html file—in the code window, and finally click on 17.
- Now, run the demo in Chrome—we will see it paused; revert back to the developer toolbar where line 17 is highlighted. The relevant calls to the jQuery library are shown on the right-hand side of the screen:
- If we double-click on the n.event.dispatch entry on the right, Chrome refreshes the toolbar and displays the original source line (highlighted) from the jQuery library, as shown here:
It is well worth spending the time to get to know source maps—all the latest browsers support it, including IE11. Even though we’ve only used a simple example here, it doesn’t matter as the principle is exactly the same, no matter how much code is used in the site.
For a more in-depth tutorial that covers all the browsers, it is worth heading over to http://blogs.msdn.com/b/davrous/archive/2014/08/22/enhance-your-javascript-debugging-life-thanks-to-the-source-map-support-available-in-ie11-chrome-opera-amp-firefox.aspx—it is worth a read!
Adding support for source maps
We’ve just previewed the source map, source map support has already been added to the library. It is worth noting though that source maps are not included with the current versions of jQuery by default. If you need to download a more recent version or add support for the first time, then follow these steps:
- Source maps can be downloaded from the main site using http://code.jquery.com/jquery-X.X.X.min.map, where X represents the version number of jQuery being used.
- Open a copy of the minified version of the library and then add this line at the end of the file:
//# sourceMappingURL=jquery.min.map
- Save it and then store it in the JavaScript folder of your project. Make sure you have copies of both the compressed and uncompressed versions of the library within the same folder.
Let’s move on and look at one more critical part of loading jQuery: if, for some unknown reason, jQuery becomes completely unavailable, then we can add a fallback position to our site that allows graceful degradation. It’s a small but crucial part of any site and presents a better user experience than your site simply falling over!
Working with Modernizr as a fallback
A best practice when working with jQuery is to ensure that a fallback is provided for the library, should the primary version not be available. (Yes, it’s irritating when it happens, but it can happen!)
Typically, we might use a little JavaScript, such as the following example, in the best practice suggestions. This would work perfectly well but doesn’t provide a graceful fallback. Instead, we can use Modernizr to perform the check for us and provide a graceful degradation if all fails.
Modernizr is a feature detection library for HTML5/CSS3, which can be used to provide a standardized fallback mechanism in the event of a functionality not being available. You can learn more at http://www.modernizr.com.
As an example, the code might look like this at the end of our website page. We first try to load jQuery using the CDN link, falling back to a local copy if that hasn’t worked or an alternative if both fail:
<body>
<script src="js/modernizr.js"></script>
<script type="text/javascript">
Modernizr.load([{
load: 'http://code.jquery.com/jquery-2.1.1.min.js',
complete: function () {
// Confirm if jQuery was loaded using CDN link
// if not, fall back to local version
if ( !window.jQuery ) {
Modernizr.load('js/jquery-latest.min.js');
}
}
},
// This script would wait until fallback is loaded, before
loading
{ load: 'jquery-example.js' }
]);
</script>
</body>
In this way, we can ensure that jQuery either loads locally or from the CDN link—if all else fails, then we can at least make a graceful exit.
Best practices for loading jQuery
So far, we’ve examined several ways of loading jQuery into our pages, over and above the usual route of downloading the library locally or using a CDN link in our code. Now that we have it installed, it’s a good opportunity to cover some of the best practices we should try to incorporate into our pages when loading jQuery:
- Always try to use a CDN to include jQuery on your production site. We can take advantage of the high availability and low latency offered by CDN services; the library may already be precached too, avoiding the need to download it again.
- Try to implement a fallback on your locally hosted library of the same version. If CDN links become unavailable (and they are not 100 percent infallible), then the local version will kick in automatically, until the CDN link becomes available again:
<script type="text/javascript" src="//code.jquery.com/jquery-
1.11.1.min.js"></script>
<script>window.jQuery || document.write('<script
src="js/jquery-1.11.1.min.js"></script>')</script> - Note that although this will work equally well as using Modernizr, it doesn’t provide a graceful fallback if both the versions of jQuery should become unavailable. Although one hopes to never be in this position, at least we can use CSS to provide a graceful exit!
- Use protocol-relative/protocol-independent URLs; the browser will automatically determine which protocol to use. If HTTPS is not available, then it will fall back to HTTP. If you look carefully at the code in the previous point, it shows a perfect example of a protocol-independent URL, with the call to jQuery from the main jQuery Core site.
- If possible, keep all your JavaScript and jQuery inclusions at the bottom of your page—scripts block the rendering of the rest of the page until they have been fully rendered.
- Use the jQuery 2.x branch, unless you need to support IE6-8; in this case, use jQuery 1.x instead—do not load multiple jQuery versions.
- If you load jQuery using a CDN link, always specify the complete version number you want to load, such as jquery-1.11.1.min.js.
- If you are using other libraries, such as Prototype, MooTools, Zepto, and so on, that use the $ sign as well, try not to use $ to call jQuery functions and simply use jQuery instead. You can return the control of $ back to the other library with a call to the $.noConflict() function.
- For advanced browser feature detection, use Modernizr.
It is worth noting that there may be instances where it isn’t always possible to follow best practices; circumstances may dictate that we need to make allowances for requirements, where best practices can’t be used. However, this should be kept to a minimum where possible; one might argue that there are flaws in our design if most of the code doesn’t follow best practices!
Summary
If you thought that the only methods to include jQuery were via a manual download or using a CDN link, then hopefully this article has opened your eyes to some alternatives—let’s take a moment to recap what we have learned.
We kicked off with a customary look at how most developers are likely to include jQuery before quickly moving on to look at other sources.
We started with a look at how to use Node, before turning our attention to using the Bower package manager. Next, we had a look at how we can reference individual modules within jQuery using the AMD approach. We then moved on and turned our attention to creating custom builds of the library using Git. We then covered how we can use source maps to debug our code, with a look at enabling support for them within Google’s Chrome browser.
To round out our journey of loading jQuery, we saw what might happen if we can’t load jQuery at all and how we can get around this, by using Modernizr to allow our pages to degrade gracefully. We then finished the article with some of the best practices that we can follow when referencing jQuery.
Resources for Article:
Further resources on this subject:
- Using different jQuery event listeners for responsive interaction [Article]
- Building a Custom Version of jQuery [Article]
- Learning jQuery [Article]