The importance of Webpack context

Today I ran into an issue testing my react-static-webpack-plugin plugin. I’ve been running webpack builds in subdirectories of the repository and then running test assertions against the output in order to test the project. So far it’s worked great, but after updating my dependencies recently I ran into a nasty error:

Error: Error: Child compilation failed:
Entry module not found: Error: Cannot resolve 'file' or 'directory' ./src/routes.js in /path/to/react-static-webpack-plugin:
Error: Cannot resolve 'file' or 'directory' ./src/routes.js in /path/to/react-static-webpack-plugin

…😖

Not good. But looking at the output and enabling the debug logger in my build process led me to the ultimate culprit, Webpack’s context.

Here’s what was happening:

  • I was running build commands from the root directory of my project
  • The builds I was running needed to be ran in their own subdirectory
  • Building directly in the subdirectory worked fine…
  • Webpack’s context was getting set to the root directory no matter what

After looking at the Webpack docs it quickly became apparent what was happening:

context in the webpack.config.js

The base directory (absolute path!) for resolving the entry option. If output.pathinfo is set, the included pathinfo is shortened to this directory.
Default: process.cwd()

I was pretty sure I knew what process.cwd() would return, so I started to have a hunch. Looking at the Node docs:

The process.cwd() method returns the current working directory of the Node.js process.

Ah, I see. Turns out that my Webpack builds which ran in subdirectories were actually searching for the entry files in the root directory of the project.

The fix was swift and effective. I added the following line to my webpack.config.js files:

context: __dirname

A refreshing dose of minimalism

Today I finished rebuilding my blog using Hexo (see last blog post for details). It’s a blog, so I knew I wouldn’t need too much JS. I started with a blank file and started coding.

Once I was satisfied with the event handling logic I had set up I sat back and reviewed my work. 44 lines including a few comments and zero dependencies. Not too bad. The web has come a long way. CSS was able to take care of a lot of the interactions and animations. But I still wanted to do better.

It occurred to me that I could actually use the :hover state to accomplish all of my open/close menu interactions. Done! A few more lines eliminated. But I still had the focus event handler I was using to select all text in a text box whenever a user put their cursor inside it. I don’t think CSS can do that… so I did end up using JS for this. I took it out of my script file and in-lined it on the input directly.

That was the last event I was handling so now I scrapped my whole JS file with its event logic. Wow! No external JS file. How novel… 😕.

All in all here is the extent of the JS I wrote for the site:

this.setSelectionRange(0, this.value.length);

Aside: I’m certainly not against large web apps—on the contrary, I love them. But for this particular project I chose to revel in the minimalism of leveraging CSS to handle almost all of my site interactions.

Migrating from Jekyll to Hexo

TL;DR: I migrated my blog from Jekyll to Hexo. This is everything you need to know to do the same.

Initializing Hexo in your existing Jekyll project

Here’s what I did:

Back up your existing Jekyll blog to a subdirectory so you can wildly make changes with impunity:

mkdir jekyll.bak

Now move all the non-git files in the directory into jekyll.bak. Initially I just did it in finder, but then I got curious about how to do it in bash. So if you want to just run a nifty command here you go:

find . -maxdepth 1 -mindepth 1 ! -name '.git' ! -name 'jekyll.bak' -exec mv '{}' ./jekyll.bak/ \;
Read More

Getting Started with Flow and Webpack

TL;DR: This post will show you how to get set up with Flow and Webpack as quickly as possible so that you can benefit from some degree of type safety in your JS code!

What are we talking about?

Flow

Flow is like ESLint on steroids. It is a static type checker for JavaScript. It let’s you add types to any existing JS code. Why would you want to do this? The short answer is because JS ❤️ runtime errors, but runtime errors make your users sad. The more helpful answer is that Flow will analyze your codebase and catch bugs that may otherwise go unnoticed until you’re app is already deployed to production. There is an entire site dedicated to explaining Flow, so I will let you check that out for more detailed information: http://flowtype.org/

Read More

Testing Webpack Plugins

TL;DR: I’m going to show you how to test Webpack plugins. I’ll even show you how to integrate with a CI server 😄. The trick is to use the Webpack Node API.

Ever built a Webpack Plugin? Ever wondered how to test that awesome plugin you just built? If so, this article is for you.

I scoured the internet (skimmed the first page of a google search) for resources on testing Webpack plugins and came up empty, so I decided it was time to take matters into my own hands!

I recently built my own Webpack plugin for generating static sites from React Router routes. You can check it out here if interested. Anyway, I was getting somewhat annoyed that I hadn’t yet tested the plugin. I had seen some regressions as I added support for more features and it was no fun to have to resolve those issues when I really just anted to generate awesome static sites using React and Webpack.

Where to turn…

Read More

The Importance of Community

Specifically, when making technical decisions.

Community his hugely important any many areas of life, but lately I’ve found that it’s particularly pertinent in making technical decisions.

An example

Recently at Trustar we started using a graph database. We have a lot of interrelated data so the graph model has made conceptual sense for a long time. So this year when we decided to implement a graph database in production we had a technical decision to make: Which database do we use?

We’re a small team (currently ~5 engineers) so we definitely don’t have the bandwidth to build our own implementation. That means we need to choose among the existing solutions. There are currently several graph database providers in the wild, and they all seem to do pretty much the same thing. Technically speaking, the usual points they hit in differentiating themselves are ones of how they handle scalability and replication.

Read More

Teaching a React.js Workshop

Who wants to be a speaker? This guy! 🙌

Ian Speaking at Real World React Meetup

Last Sunday was a significant event for me: I put on a React workshop (link here) to teach beginners how to get started with React. It was a full day event and it was a great learning experience for myself and hopefully for the students as well.

Giving back to the community

The community surrounding React has done a lot for me. It’s only been a year since I started using this technology, but it’s played a tremendous role in my personal development as a programmer. As such, I really wanted to start contributing back to this amazing community that has helped nurture my own development.

Read More

Switching Away From Mongoose

I’ve been using MongoDB as my primary database for some time now. That means all new projects I created were running Mongo, and Mongoose was my ORM of choice. Mongoose has worked well for my in the past and even still does, but I can feel that it’s time for a switch.

Why the change?

Mongo

The main reason actually isn’t Mongoose, but rather Mongo. The data in most applications is probably going to be relational so why would you use a non-relational database? The main reason I liked Mongo initially was that it had a JavaScript API but I’ve come to realize that doesn’t matter that much, and it can even be a hindrance when working with team members that know and love SQL.

Mpromise

For anyone who doesn’t know already, Mongoose provides a promise-based API for doing async database operations in addition to the classic callbacks. This API is unfortunately under documented, but it exists none-the-less and the library it uses to implement promises is Mpromise.

Mpromise seemed fine at first, but it turns out it simply doesn’t adhere to the ES6 Promise spec. The most glaring example of this is that Mpromise does not implement .catch, meaning you can’t do nice pretty error handling at the bottom of your then-stack. Here’s an example using Express to build an API:

import Model from '../models/Model.js';
// GET all the Models
api.get('/models', (req, res, next) => {
Model.find({})
.then(data => res.send(data))
.catch(next);
});
Read More