Tech

Tales from my 2024 mini retirement

Hiring in tech has slowed to a grinding halt, and I'm currently looking for work. But rather than stress out about securing my next gig and spending every day overconcerned with what's going to happen next, I'm taking this time away from paid engineering work to stop and smell the proverbial roses.

The concept of the mini retirement isn't new. It was a term popularized by Tim Ferriss, and refers to taking a set amount of time away from paid employment to reset, retool, and enjoy life.

For my entire career, I've always had one project or another on my plate. This has meant that, whatever I was set to do for the day, part of it was occupied by the day-to-day responsibilities of the project. I've always been a diligent saver and in some ways have hoped the day would come where I didn't have any paid work for a period of time. In fact, I remember at one point hoping for a recession in the tech industry.

At the beginning of this period of idle time, I felt a sense of dread. My income sources have dried up and I'm burning through my savings. But nothing in life is guaranteed, and what is our savings for if not for supporting us?

This realization has given me the courage to stop trying so hard to secure new work right now. Would I rather spend these months (or years?) constantly worrying about the future, or calmly enjoying these precious days, which, I will never recover?

I struggle with generalized anxiety and the state of my finances are no exception. But I realize I'm in a better position than most to weather this storm. I have no children, no mortgage, no car payment, no student loans. I have lived in my van and could do it again if I had to. I am creative by nature and constantly strive to learn new things. These facts all give me confidence that I can kick back and enjoy this period of idleness knowing I've set myself up for success.

So far, I've occupied myself with several personal projects:

  • Gigbot is my Git-inspired remote tech job aggregator for the command line. I've been using it to quickly peruse the most recent remote tech job listings across multiple job boards.

  • I've been working on an HTML-based printable booklet zine engine, using my original art and writing as content. The zine is called EPHEMERA and I'll be publishing it here soon.

  • I started a new Discord server called AI Took Our Jobs, as a place for tech workers to help support one another during the current downturn. Email me if you'd like an invite!

  • Taoverse prints a random verse from the Tao te Ching on the command line. I run the command in my .zshrc to print a verse every time I open a new terminal window.

  • I've been working on a new ebook about bohemianism and how to use its tenets to live a more storied, meaningful, creative, and adventurous life.

  • I've been decluttering by photographing and posting my unused stuff on Craigslist for sale, as well as digitizing personal notes, greeting cards, and documents I want to save but don't want to have to carry around with me.

  • I've been casually learning more about machine learning using TensorFlow from free books and tutorial videos online.

All in all, this period has proven to be productive and exciting. I'm learning a ton and I recognize how lucky I am to have the resources to pursue my own projects during this time. What will happen next? None of us can be sure. And that's why it's important to take it easy, man.

Adding React to a Middleman project with Webpack

Middleman is a static site generator written in Ruby. It's a great way to produce rich static content sites without the need for a server. Despite this, it doesn't come with internal support for modern JavaScript frameworks like React. Luckily, Middleman 4 ships with a feature called External Pipeline which allows wiring in your own external build tool like Gulp or Webpack.

Let's look at how to integrate Webpack with Middleman for the purpose of using React on our site.

Install development dependencies

First, let's install the dependencies we'll need to build our React code. Note that we're using the --save-dev flag to indicate to npm that we should append these libraries to the devDependencies section of our package.json.

$ npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react webpack uglifyjs-webpack-plugin
  • babel-core is the core Babel package for transpiling ES6 and JSX into browser-friendly ES5 JavaScript.
  • babel-loader is a Webpack loader which loads files from our path into Babel.
  • babel-preset-es2015 is a preset for Babel to transpile ES6 code.
  • babel-preset-react is a preset for Babel to transpile JSX code.
  • webpack is Webpack itself.
  • uglifyjs-webpack-plugin is a Webpack plugin to uglify and compress our code for production.

Install React

Next, install the React packages, this time using --save to indicate these are runtime dependencies:

$ npm install --save react react-dom

Set up your Babel configuration file

Babel has its own configuration file inside .babelrc. Create this file in the root of your Middleman project with the following contents:

{
  "presets": [
    "es2015", "react"
  ]
}

This file tells Babel to use the es2015 and react presets we installed in the first step.

Configure Webpack

Next we'll configure Webpack with a basic configuration file that supports both development and production environments. Place the following inside the file webpack.config.js in the root of your project:

// webpack.config.js
var webpack = require('webpack');

const isProduction = process.env.NODE_ENV === 'production';

const productionPlugins = [
  new webpack.DefinePlugin({
    'process.env.NODE_ENV': '"production"'
  }),
  isProduction ? new webpack.optimize.UglifyJsPlugin({
    compress: {
      warnings: false,
    },
  }) : null,
];

module.exports = {
  entry: './assets/javascripts/index.js',
  devtool: isProduction ? false : 'source-map',
  output: {
    library: 'MyApp',
    path: __dirname + '/tmp/dist',
    filename: 'bundle.js',
  },
  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: 'babel-loader',
        exclude: /node_modules/
      }
    ]
  },
  plugins: isProduction ? productionPlugins : []
};

Notice that we use the isProduction flag to toggle the use of the UglifyJsPlugin as well as whether we use a devtool to provide us with source maps for debugging.

Configure Middleman to build Webpack

Now that we've configured Webpack, let's tell Middleman to execute it whenever it rebuilds. To do this, we'll activate the external pipeline plugin in our config.rb and point it at the Webpack executable:

# config.rb

activate :external_pipeline,
  name: :webpack,
  command: build? ?
  "NODE_ENV=production ./node_modules/webpack/bin/webpack.js --bail -p" :
  "./node_modules/webpack/bin/webpack.js --watch -d --progress --color",
  source: "tmp/dist",
  latency: 1

When we run middleman build, we run Webpack with NODE_ENV=production. This triggers our production build options in our Webpack configuration.

When using middleman server though, we tell Webpack to --watch for changes and automatically rebuild.

Middleman will look for the result of our built assets inside tmp/dist. Let's go ahead and create that directory now:

$ mkdir -p tmp/dist

Build an example React component

Now that we've got our tooling configured, let's create a simple React component to test that everything works. First, create a directory to store your Webpack JavaScript assets. I place these files in assets/javascripts since Sprockets looks inside source/javascripts, and I don't want Sprockets to attempt to build my React code.

$ mkdir -p assets/javascripts

Next, let's sketch out a React component. Note that from index.js I'm exporting a function renderHello which renders the HelloWorld component to a DOM element specified by ID. This allows us to call upon fragments of React code from within existing pages.

// assets/javascripts/index.js

import React from 'react';
import ReactDOM from 'react-dom';

const HelloReact = props => (
  <div>Hello, React!</div>
);

function renderHello(id) {
  const el = document.getElementById(selector);
  ReactDOM.render(<HelloReact />, el);
}

export default {
  renderHello
}

Mount the component

Finally, mount the component onto an existing DOM element on a page. First include the built bundle.js file. Then, call renderHello:

  <body>
    <div id="hello">
    </div>

    <%= javascript_include_tag  "bundle" %>
    <script type="text/javascript">
      MyApp.default.renderHello('hello');
    </script>
  </body>

Other resources

A notificationless life

I'm an anxious person.

Wait, strike that. I'm striving not to carelessly apply labels. I sometimes suffer from anxiety. There. That's better.

I sometimes suffer from anxiety. Having spent the majority of my waking adult life in front of a screen, I'm no stranger to the anxiety-inducing nature of life online in 2017. The average computer or smartphone user has hundreds of apps vying for their attention, each hoping to take a slice.

It didn't used to be this way. Before 2009 and the introduction of Apple's Push Notification Service, your iPhone left you alone except for when you received a phone call or a text message. Those were simpler times.

Now, if we don't do something about it, we're subject to a near-constant buzzing and chirping. Emails. Text messages. Tweets. Likes. It doesn't stop. As a technologist, I feel almost apologetic for the culture of distraction that is now our everyday reality.

That's why I want to do you a favor. I'm going to make a suggestion that hopefully will change your life for the better. Ready?

Turn off all your notifications.

That's right. Turn them all off. Even your text messages. Maybe leave your phone call notifications on so people can reach you in case of an emergency. But you haven't experienced the serenity the people of the twentieth century took for granted until you turn off all your smartphone notifications.

Afraid you'll miss something? You won't. If something is important enough, someone will call you.

Alias your common Ruby commands for a faster workflow

If you're a Rubyist, you probably use the likes of rspec, cucumber, rake, and other commands frequently. And it's likely that you might be running them using bundle exec to execute them in the context of your project's bundle. After finding I was spending a lot of time typing each of these commands, I added a few aliases to my shell config to speed up my workflow:

alias rsp='bundle exec rspec'
alias cuc='bundle exec cucumber'
alias rak='bundle exec rake'
alias mm='bundle exec middleman'

Paste these into your ~/.bashrc or ~/.zshrc, restart your shell, and now running an rspec test in the context of your bundle is as simple as:

rsp spec/models/banana_spec.rb

Have other useful aliases? Post them in the comments below!

A Jasmine matcher for Backbone.js Event Expectations

I wanted to be able to eloquently test Backbone.js event chains, so I wrote a custom matcher.

Adventures into Python

The office has been much more forgiving as of late and has given me more opportunities to learn different programming techniques. I have recently started learning wxPython, a Python GUI library based off wxWidgets. So far it has been an interesting experience and I’m really enjoying developing actual applications rather than mundane VBScript/SQL database web applications.

I’d like to start developing in Python more now that I’m more familiar with the syntax. It’s an excellent language once you get past the obscure syntax and can be quite efficient.

We’ll see what I come up with…