InuitCSS and Gatsby - My First Plugin

Thursday, 10th September, 2020
Here's to your first Gatsby open source contribution

Good old JavaScript

Ever since my first dealings with JavaScript, programming the status bar of Netscape Navigator and bringing up annoying alert boxes, I've seen plenty of JavaScript frameworks come and go; but never two JavaScript projects created exactly the same.

Coming from a Ruby on Rails background, seeing the effort many JavaScript developers are making in bespoke state management, custom integrations and boilerplate, I'm always impressed at some of the ingenious ways that wheels are reinvented over and over again. Not to mention the compendium of project naming conventions and folder structures.

Part of the problem is the language itself. JavaScript must be the most pramatic invention in software, if not the entire world; being used in cases well beyond the original brief of its creator. It's flexibility is both a strength and a weakness: "too much rope to hang yourself" is an idiom I've heard used many times with JavaScript.

So efforts to consolidate and focus development efforts towards greater productivity are welcome, in a world where the tooling is for me a barrier to learning and often creativity.

The Great Gatsby

Over the last year or so, I've been following the progress of the GatsbyJS framework with interest. It's a static website generator, built upon React.js and Redux, perhaps the toolchain that has emerged as the closest thing to a consensus in JavaScript web development. By taking these tools and providing sensible opinions for project structure, routing and other day to day tasks, it approaches something of a positive web development experience.

In hindsight, there are many websites that I built in Rails, backed by a SQL database, that could and should have been built using the approach espoused by Gatsby (Middleman in Ruby was an excellent solution I thought). Why have live calls to a database to generate content over and over, if that content doesn't change often? Better to render it in advance and serve the static file straight out of a CDN. Simple, effective and fast.

Gatsby's approach makes building a modern, single page application seem straightforward. But what about when you need features beyond the core functionality? It's rich plugin system provides plenty of ready-made libraries take take the pain out of the day to day of building your site.

CSS in JavaScript? No Thanks!

One trend I've seen in React projects is the use of styled components, essentially a way of applying inline styles to the resulting DOM elements created by React. It's proponents point to the simplicity of keeping the CSS and JavaScript located together and bundled together, with the same compression benefits and reduced HTTP requests for separate stylesheets.

For me, the benefit of keeping code separate from each other is an old habit that hasn't gone away. Even JSX, as pretty as it might be in a small, functional React component, is essentially a hack to mix HTML and JavaScript, the 'View' and a 'Controller'. If a Ruby on Rails developer wrote code like that, it would be roundly criticised. In React, it's the norm. (I think Vue.js's approach of using templates is cleaner, but I'm trying to avoid spreading my learning too thin at the moment)

Then there's the loss of tooling, and in my case, existing style guide code that I'd written in SASS and didn't want to throw away. I've been using an object-orientated CSS framework called Inuit for many years, drawn by its tiny footprint and elegant defaults, that allow me to build a tight design. The loss of control over DOM structure and CSS in JavaScript component libraries seems enough to give me pause; it might make sense if you don't have a design, or are rapidly prototyping; but otherwise I find myself fighting against a theme or compenent library, or guessing what it's doing under the hood.

When I tried to incorporate Inuit into my Gatsby project, I found that it wasn't entirely straightforward. There were a couple of manual steps, which I knew I'd forget if I ran them infrequently, once per project. So I thought this would be a good excuse to learn how the plugin system worked.

My first Gatsby Plugin

Gatsby provides for extensions of the core framework through a plugin mechanism. A plugin is essentially just an Node.js package, with some Gatsby conventions. Developers can access the Gatsby API, to hook into various lifecycle points during the build process, for instance pulling data from somewhere and dynamically creating pages from it. In my case, the plugin is relatively modest; it doesn't create any Redux state. Essentially, it is just moving files into place, and ensuring that the SASS is being loaded correctly.

Using a yarn monorepo, development is smooth, using a template gatsby project to test drive the plugin, which also serves as live documentation on how to use it. I needed to access a hook onPreInit, which runs upon the initialisation of the gatsby dev server or build process.

I then use a little trick to dynamically find the path to the inuitcss node module, using require.resolve('inuitcss'). This returns the path to where yarn installed the module, rather than making assumptions about relative paths if the end user installed their module elsewhere. I then extract the manifest files that inuit css uses to configure the framework, allowing the end Gatsby developer to start writing SCSS.

After that, to publish a plugin was a simple step of writing a README and publishing an npm package. By adding some keywords to the package.json, I was impressed to see the plugin magically appeared on the Gatsby plugin library later that day.

Don't drop your CSS right inuit (...sorry)

So the next time you're tempted to use styled components, why not consider keeping your SASS/CSS separate, and focus on object-orientated, reusable, readable and extensible CSS, and regain control of your frontend development! And do it in Gatsby!