Software Engineering in WordPress and Musings on the Deep Life

My Strategy For Organizing JavaScript in WordPress

Yesterday, I shared my strategy for using LESS in WordPress and enjoyed the comments that followed. In that post, I also mentioned that I have a similar strategy that I use to maintain my JavaScript files.

This particular aspect of development is one that I’m still experimenting with; however, there are certain aspects of it that have remained constant.

To follow up with yesterday’s post, I thought I’d share several things that I’ve consistently done that have improved development as well as some of the things that I’m currently doing that are proving to be useful.

With that said, here’s my current strategy for organizing JavaScript in WordPress.

Before covering how I organize my JavaScript files, note that I use CodeKit to manage my LESS files and JavaScript assets in my WordPress development. I mention this not because I think it has to be done (though I obviously believe it makes it easier), but also because it automates using some of the available tools such as JSLint.

1. Directory Structure

My Strategy For Organizing JavaScript in WordPress - Directory Structure

For the most part, my directory structure models the following structure:

  • In the root of the theme or plugin directory, there is a js directory. This directory is where all minified JavaScript files live. This includes third-party libraries and my files all of which are minified
  • In the js directory, I maintain a subdirectory named dev where I keep all of my pre-linted, pre-minified JavaScript sources. I used to keep all of my files along with third-party libraries in this folder, but I’ve since begun keeping third-party dependencies in another subdirectory usually called lib.
  • At the absolute minimum, there will be a single less file: theme.js which includes the basic JavaScript for a theme; however, I often include  admin.js which is used to handle behavior in the dashboard.
  • Once linted and minified, all files are written to the root of the js directory and suffixed with min.js.

When I’m working on a plugin, then I’ll use the name for plugin.js and if I’m working on a widget, then I’ll name the file widget.js.

2. On Using JSLint

When it comes to JavaScript code quality, JSLint and JSHint are arguably the two most popular tools. The primary difference is this:

  • JSLint is written and managed by Douglas Crockford. It enforces a strict set of rules and the coding conventions as prescribed by him.
  • JSHint is a derivative of JSLint that is arguably a bit more relaxed, and is managed by a community rather than a single person.

Generally speaking, I think using either tool is fine as long as you’re consistent (after all, you want your coding conventions to be consistent, right?), but I’m actually a fan of JSLint primarily because I like Crockford’s standards and style.

He’s the author of JavaScript: The Good Parts which I believe to be to JavaScript what K&R is to C, and that particular book changed the way that I write JavaScript.

3. Code Modularity and Including Files

In the comments of yesterday’s post, we discussed a modular approach to LESS-based development. Though I tend to think this is managed on a per-project basis, I generally create separate JavaScript files depending on the page to which they’re supposed to run.

For example, in a current project I have pages for:

  • Registering Users
  • Updating Profiles
  • Sending data to the server via Ajax

As such, I have three separate JavaScript files:

  • register.js
  • profile-update.js
  • story-submit.js

Then, on the server-side, I include each of these files whenever that specific page is being viewed.

For example, I use a single.php template for users submitting stories, so I have this in functions.php:

if( is_single() ) {
	wp_register_script( 'story-submit', get_template_directory_uri() . '/js/story-submit.min.js', array( 'redactor-js' ) );
	wp_enqueue_script ( 'story-submit' );
} // end if

This way, I’m only loading the files when I need them keeping the number of HTTP requests down, I don’t have to do any element checks in the JavaScript itself, and it makes the practice of progressive enhancement much easier.

All of that said, there are still things with which I’m experimenting, but these are the things that have remained constant throughout my last few projects.

As usual, I’m always interested to know how you guys organize your files, too so feel free to share them in the comments.

6 Comments

  1. Jason Bradley

    Good stuff Tom. Keep it coming. Have you used require.js with WordPress at all?

    • Tom McFarlin

      I’ve not – I’ve used head.js on a couple of projects in the past, but haven’t in anything recently.

  2. Boris

    Developers argue usually a good deal about wp_register_script and wp_enqueue_script. Personally, I prefer to register all my scripts first and then enqueue them later when needed with just the handle. In your code example above it doesn’t really make sense to use both functions, though, as the story-submit script will only be registered and enqueued on a single post.

    Extensions and add-ons for your plugin or theme will have to register the script again when on another page and won’t be able to just enqueue it via the handle. If your project is not meant to be extensible, then it’s not an issue, but you never know what might happen.

    Basically, I register all scripts at init and then enqueue them conditionally at wp_enqueue_scripts.

    • Tom McFarlin

      You’re absolutely right. In the example above, the call to register is redundant and isn’t necessarily needed – I could get by just fine with calling enqueue.

      I’m more of a fan of your approach – register first, then enqueue when needed.

      As far as extensibility is concerned, this is taken from a web app, so it won’t have any child themes or dependent plugins or anything like that, so it’s a non-issue (though a valid point!).

  3. Chris Wallace

    Wow, that’s the most Javascript files I’ve ever seen in one theme.

    • Tom McFarlin

      Seriously. This shot is actually taken from a web app being built on top of WordPress.

      There’s a lot of different parts for several different areas, so keeping things separated has been better – especially for debugging – than having a single, giant file.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

© 2023 Tom McFarlin

Theme by Anders NorenUp ↑