Ceiba Web

Defining a JavaScript Stack

Mario Vega

20 June 2018

I'm going to take a moment to describe what JavaScript libraries I find essential enough to include in every project. I distinctly recall this being a major sticking point for me as I stumbled towards full-stack development.

Above is the package.json for the jukung theme which I've created as a blank theme using the Statamic CLI.

For those who might be unfamiliar, package.json files are used to define any packages that will be used in your project by Node.js. Node.js, in turn, is the standard JavaScript library for working with JavaScript files on your server.

At one point this distinction confused me to no end. As a budding WordPress developer encountering the JavaScript ecosystem for the first time, I had no idea why I would want to introduce a JavaScript library amongst my PHP files. Writing JavaScript directly in my template files had worked just fine for me so far. Why did I need to complicate things by adding Node into the mix, especially if I was using PHP and not JavaScript to power my servers?

When considering whether or not to include something in my development process, I try my best to follow a simple rule: when you need it, you'll know, and don't worry about it before then. In the mercurial and evolving world of web development, the temptation and the social pressure to learn new tools never goes away. If you stick with what works for you until it doesn't work for you, you can avoid that pressure — but when something doesn't work for you, it's important to know why, as well as how to fix it.

I will admit that the path that led me into the world of JavaScript build steps originated from my background in writing. Because my interest in writing predates my interest in programming, where possible I try to program in a style that mirrors good writing. For me, this means writing code and documentation that explains what's going on in my code as clearly and explicitly as possible, even if this means being more verbose than many programmers would like.

This also leads to my preference for declarative programming, which, as the name implies, is a style of programming that declares what your code does at the highest level possible. Vanilla JavaScript is fantastically powerful, but it is not declarative by nature — instead, it is procedural, which involves solving problems through a defined series of steps.

Even though my web server runs on PHP, in order to fully embrace declarative programming, it's helpful to utilize some features and functions that are only available using non-standard JavaScript tools and libraries. Because of this, I find that a build step, which converts non-standard JavaScript into a form that works correctly on browsers across the Internet, is useful enough to incorporate into my development process.

Now that we know why a build step is useful, let's go over the package.json file in a bit more depth. The two important parts to this file are the dependencies and the scripts, which describe what JavaScript packages my Statamic theme uses as well as how those packages should be combined and delivered to the browser.

The three packages of particular importance here are vue, laravel-mix, and tailwindcss. Vue is my preferred JavaScript library to achieve the declarative programming style mentioned before, and Laravel Mix is a tool that makes creating a build step as easy as possible. Using Laravel Mix, you can write JavaScript using modern techniques without worrying about your code being too "fancy" to work on any device, from your MacBook or Surface Pro to your dad's Nokia flip phone.

Finally, TailwindCSS is a library I use to eliminate the troubles of maintaining a huge bundle of repetitive CSS files. This will definitely need to be its own series, as there's a lot to cover regarding the benefits and disadvantages of working with TailwindCSS. Suffice it to say for now that after writing CSS by hand for years before using Tailwind, I find it very hard to return to writing CSS the "normal" way.

The scripts part of the package.json looks opaque, even to me. Fortunately you don't have to write this code by hand: Laravel Mix includes some scripts that will work out of the box. I've copy-pasted their code into my setup directly.