Modern JavaScript and WooCommerce 101

Introduction

This guide is intended as a high-level overview of the modern WooCommerce development environment and how new tools and features such as an increasingly React-based user interface fits into the broader user experience and development environment.


Assumptions

This guide assumes you are well acquainted with traditional WordPress development tools and concepts such as HTTP requests, static assets, actions, filters, and other pieces developers typically encounter when building solutions with PHP, HTML, CSS, and JavaScript (or libraries like jQuery).

It also assumes that you have some familiarity with modern JavaScript concepts, but many tools and concepts will be covered at a high level in this guide. Throughout the guide, there will be links to relevant documentation and resources that you can explore to help expand on the topics this guide covers.

Recommended foundational reading

If you have not worked much with JavaScript, or if your familiarity with JavaScript in WordPress has centered on libraries such as jQuery, we recommend taking some time to explore the resources below for a primer on some of the concepts that this guide covers.


Overview

To understand how modern JavaScript fits into WooCommerce development, it’s helpful to take a step back and look at how legacy WordPress environments function.

The traditional way

For the sake of simplicity, we’ll say a legacy WordPress environment is one that does not rely on any modern JavaScript features or tooling. In this environment, we could say that the the atomic unit of user interaction is most often the page-level HTTP request, which typically follows a predictable flow:

  1. A person interacts with WordPress by clicking links and buttons or perhaps submitting form fields, at which point their browser sends an HTTP request for a particular resource (URL).
  2. WordPress receives the request and uses it to decide what kind of processing must be done to return the correct response to the user’s browser. For instance, WordPress may need to communicate with its underlying SQL database to perform CRUD operations on records, fetch data from external services, concatenate template files, or any number (and combination) of different operations.
  3. As WordPress processes a request, it encounters points in its execution where additional behavior or data can be plugged in to modify the default processing of the request. These are the Hooks and Filters that make so much of WordPress’ extensibility possible.
  4. Once WordPress has finished processing the request, it returns a response to the browser, which, more often than not, takes the form of a rendered HTML page in the user’s browser window.

In this environment, there may be some nominal use of vanilla JavaScript or libraries such as jQuery to handle lightweight client-side functionality in the browser, but the overwhelming majority of meaningful functionality comes from server-side processing that occurs as a result of HTTP requests that cause a full reload of the browser page.

Note: From a technical standpoint, the steps outlined above are admittedly an oversimplification of a much more complex process, but for the purposes of representing the user’s interaction, these steps provide a sufficient sketch of what’s happening.

The new way

In a Gutenberg-era WordPress environment, which interweaves modern JavaScript with the traditional PHP functionality, the balance of responsibility between the client side and server side of the application shifts. While some of WordPress’ functionality is still tied to page-to-page navigation and server-side rendering of HTML, much more of its functionality is driven on the client side. Server-side processing can occur asychronously using AJAX, which precludes the need to reload an entire browser window just to communicate with the server. Likewise, instead of requiring server-side template rendering, this environment can programmatically load HTML elements as needed and repaint a browser page by modifying it’s DOM directly.

The result is a user experience that much more closely resembles the behavior in desktop applications, where functionality is event driven and based on granular user actions, such as clicking a button, pressing a key, or hovering over an element. Because of this distinction, it’s more difficult to express the typical user interaction as a single series of steps like we did above. Things are much more fluid and varied, but there are a few key concepts worth highlighting in this new paradigm.

Pre-processing

Because modern JavaScript uses syntax and features that not all browsers understand, it is necessary to pre-process source files using one or more utilities that transpile the source files into a cross-compatible format, as well as a static module bundler that packages your transpiled code into a single, browser-ready JavaScript file.

Componentization

HTML elements are defined using JSX inside of modular React components. These components are typically nested into a component hierarchy with a shared application state. A component hierarchy is inserted into the corresonding page’s DOM when the element is needed on the page. This insertion can happen when the script loads, during an initializion function, or even, in the case of WordPress and WooCommerce, as the result of an action or filter hook.

Granular event-driven behavior

HTML elements are rendered with event handlers that are bound to their DOM events. These event handlers process the events and update the shared state, which in turn causes the nested elements to automatically re-render as needed.


JavaScript Tools

This modernized user experience requires its own dedicated tools for development and testing, many of which may be unfamiliar if you have primarily worked with PHP. Let’s take a look at a few of those tools and what you’ll use them for.

Node.js

Node is an open-source and cross-platform JavaScript runtime environment. It allows you to write code that interacts with filesystems, accesses databases, and lots of other server-side functionality, completely in JavaScript. It has a rich ecosystem of libraries and packages that you can freely use (see NPM below). The majority of these are written using non-blocking paradigms that allow you to have concurrent operations in a single-threaded event loop.

In a WooCommerce development environment, Node provides much of the underlying workflow tooling that supporting libraries use to manage the development lifecycle in projects that are powered by modern JavaScript.

NVM

NVM is a version manager for Node.js. Different projects might require different versions of Node. This tool helps you maintain multiple installations of Node on your system and switch between them as needed.

NPM

NPM is a bit like a Swiss Army Knife for Node applications. It consists of a website that hosts a registry of packages that you can explore and use in your projects, as well as a command-line utility that you can use to interact with the registry and manage the development workflow in your projects. In a WooCommerce development environment, you’ll use it to:

  • Declare and install dependencies
  • Run build scripts that orchestrate tools which transpile and package your source files into servable assets
  • Assist with general development tasks such as linting, testing, and all sorts of other things

Node Packages

A WooCommerce development environment relies on a number of different Node modules as dependencies for various things. Outlining each dependency’s functionality and purpose is outside the scope of this guide, but we recommend exploring the dependencies and devDependencies objects in the package.json file of the WooCommerce Admin repository to get an idea of what kinds of modules a modern WooCommerce extension might use.

One package worth highlighting here, however, is a utility that handles a critical piece of your development workflow: Webpack.

Webpack

Webpack is a static module bundler that handles a number of important tasks to prepare your source files for a production environment. It reads through your files to create an internal dependency graph, which it uses to create self-contained bundles that have everything a project needs. Out of the box, Webpack only processes JavaScript (and JSON) files, but you can use Loaders to read and process other file formats. You can also take advantage of Plugins that will transpile your files from one format to another. WooCommerce and its supporting extensions, such as WooCommerce Admin, all make use of Loaders and Plugins in order to process source files into servable assets.


Architecture of a project

Building an extension for WooCommerce with modern JavaScript requires a hybid development approach that incorporates the elements of a Node project into the typical architecture of a WordPress plugin.

If you are interested in exploring the architecture of a basic WooCommerce extension that incorporates modern JavaScript, there is a breakdown of a simple example in the Extension Architecture section of the WooCommerce Extension Developer Guide. The guide includes an overview of the files that are common in WooCommerce extensions, as well as an explanation of how some of the more complex configuration files are composed.


Basic Workflow

When integrating a modern JavaScript workflow into a WooCommerce extension, the basic process is relatively straightforward:

  • ✅ Update your version control configuration to ignore the the superfluous supporting files that Node generates.
  • ✅ Initialize a package.json file.
  • ✅ Declare and install dependencies.
  • ✅ Configure a build process using Webpack or a similar tool that will combine, transpile, and minify the JavaScript you write.
  • ✅ Create a dedicated directory in your project to house the JavaScript you write.
  • ✅ Run your build process to generate a browser-ready JavaScript asset.
  • ✅ Register the minified JavaScript in WordPress and enqueue them to load alongside the other admin scripts.

If you have an existing extension and you want to incorporate a modern JavaScript workflow into your existing project, take a look at this tutorial on adding React to an existing extension. If you are starting from scratch, we recommend using the WooCommerce Extension Generator that is bundled with the WooCommerce Admin repository. It creates an extension that lets you take advantage of lots of shared helper scripts and preconfigured tools.