Classic Node.js® package round-up

A strange game I play: analyzing the subset of our zeitgeist I’m attuned to for assymetric attribution. An honorific such as “The Queen of (x)” or some intangible social capital like “flava”. Attributions essentially tethered to core homoperceptualities are my favorites. The fugacious “It Girl” assigned by the sentinel-like Zeitgeides of the premillenial epoch; The bobo-ensconced idol sconce “visionary”, melding 1972 introversion w/ 1984 egostalwartism within a hero-worship eggshell.

I played it today with two of my favorite jams: music & code. Groups, songs, genre & instruments can be classic. They can be “out” and then “in” again. They can be “underground” or “over-the-top”. Software teams, modules, formatting styles, design patterns & text editors are rarely attributed anything approaching that. Text editors come closest, right? You might even start to think of some rationalizations for that. I did for a few seconds, I’ll lay it down for you brothers & sisters:

  1. Text has remained the dominant way of producing (with slight ebbs & flows)
  2. Continual waves of new types of programmers get introduced to *nix platforms, leading to recontextualization & innovation of old cores like vi
  3. vi et al have been carried through multiple OSes, resulting in a cross-generational dialog centered around them
  4. Text is the only part of programming everyone understands & uses
  5. More personal customization & time is spent in a particular editor than anything else

But I stopped there. Why? Each of those are wholly true for other aspects of programming, contradicted clearly by the musical comparison or just aren’t true! In the end, much of what prevents us from emotionally enjoying code culture in the same way as other pursuits comes down to arbitrary cultural viruses. Artificial constructs, prejudices, overcompensation & lack of respect form an ever-ready thought army. By telling ourselves it’s a science when it’s not. By calling ourselves engineers when we’re not. By acting like software needs to be free to download to be pure of intention. By holding up the solitary genius as a symbol of worship when the real deals are the teams of diverse skills & approaches that are required for building something game-changing.

But wait—that’s not all!

There’s a much bigger elephant in the room. One that’s propagated by (understandably) ignorant recent college graduates given too much cachet just for being you, Ivy League & easy to drive toward 24-hour work days. It’s propped up by personal reward-starved senior devs w/ impostor syndrome in an industry with no career growth opportunities for technical people. It’s carried along like a dormant virus by non-technical folks who care too little technically & too much politically. The Tethytheria I speak of? The bold-faced lie that there’s always something new and more advanced in the works by software architects. The lie that software devs are “engineering” (that word again…) the next big thing based on “computer science” that will solve all the problems the last thing they made created. Never mind they weren’t able to clean up the mess the previous thing left. I’m not just talking about “new things aren’t necessarily better ladies & gentlemen”. Some of you, maybe even a lot of you, already understand that pretty darned well. Anyone who’s been using new iPhones for the last 4 years knows that! A bbbiiiggg slice of this fib pie here is filled with “this stuff isn’t even new” fruit! Hell, it’s moldy as hell by the time some 6-figure a year emotionally stunted bro-baby is “giving a talk” about it at Moscone Center or the Marriott Marquis. Check the expiration date! From functional programming to reactive programming; top-down render to configurable code prettifiers. Back & forth between separation & localization, loosely-interfaced event buses & strictly-defined static object relationship maps, tighly-controlled turn-key developer ecosystems & loose DIY warehouses of molecular building blocks. These aren’t the echos of a steady upward trend toward an ideal. They’re the same cyclical gyrations humans make in all their endeavors.

So if we’re going to be the silly humans we are anyway—why not let programming be the great creative madness it’s destined to be? Enjoy the classics. Enjoy the greatist hits. Love the chart toppers & the underground wonders. There’s joy to be had in all of that. And guess what? We can still try to get better.


"constructor" as an Anti-Pattern in React.Components

“The ties that bind us are stronger than the occasional stresses that separate us.”
― Colin Powell, It Worked for Me: In Life and Leadership

“The state assignments & bind calls in constructor are no longer worth the stress & should be separated from our code.”
James J. Womack, It Worked for Me: In Code and Componentry

Instead of getting poetic about what that means, I’ll show you an image:

Other than the class name, that’s real code from my employer. It’s an extreme case where way too much is going on in one component, but some version of that dance is happening in about half of the React components I’ve seen at Netflix.

I won’t get into the historical reasons folks have done that, and focus on the present. In the present, it’s not necessary if you’re using Babel to handle JSX.

Let’s take a less extreme example and refactor it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
export default class NewClusterPanel extends Component {
constructor(props) {
super(props)
this.onChildClick = this.onChildClick.bind(this)
this.onParentClick = this.onParentClick.bind(this)
this.state = {
search: ""
}
}
onParentClick(e, newValue) {
this.props.setUIProperty(this.props.uiProp, newValue)
}
onChildClick(e, newValue) {
this.props.setUIProperty(this.props.uiProp, newValue)
}
}

That’s a lot of noise in constructor just to set a default search string & ensure your methods contain “this”. Let’s try the same thing w/ stage 3 class properties:

1
2
3
4
5
6
7
8
9
10
11
export default class NewClusterPanel extends Component {
state = {
search: ""
}
onParentClick = (e, newValue) =>
this.props.setUIProperty(this.props.uiProp, newValue)
onChildClick = (e, newValue) =>
this.props.setUIProperty(this.props.uiProp, newValue)
}

Nice, huh? If you want to use this approach in your React projects, try npm i babel-preset-netflix-dea.

Later!


Delicious ES2017 Curry

I came across this post recently. It gives the usual JavaScripty overview of currying, which is to say it does some good but also conflates a number of concepts and sacrifices functional purity for compatibility with accepted thought in the JavaScript community. I’ll let other folks address the annoying level of syncretism in posts such as that. What I’ll do is provide you with a simple curry implementation that has these simple improvements over that found in the helpful CarbonFive post:

  1. Gets rid of the semantic noise
    • Non-clarifying intermediate declarations that are only used once
    • The method call & null required when using ::call && ::apply to manipulate how functions are called
  2. Gets rid of prototype trickery (Array.prototype.slice.call.blah.blah.blah)
  3. Takes advantage of the latest JavaScript features in a way that increases declative code and decreases imperative code
  4. Gets rid of magic values such as arguments

Here it is:

1
2
3
4
5
6
7
8
9
const curry = uncurriedFunction => {
const curriedFunction = (...args) =>
args.length >= uncurriedFunction.length ?
uncurriedFunction(...args) :
(...args2) =>
curriedFunction(...([ ...args, ...args2 ]))
return curriedFunction
}

The original from CarbonFive:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function curry(fx) {
var arity = fx.length;
return function f1() {
var args = Array.prototype.slice.call(arguments, 0);
if (args.length >= arity) {
return fx.apply(null, args);
}
else {
return function f2() {
var args2 = Array.prototype.slice.call(arguments, 0);
return f1.apply(null, args.concat(args2));
}
}
};
}

We now have a curry implementation that is somehow both shorter and easier to understand. Instead of meaningless declarations like f1, we’ve curriedFunction et al. We’ve traded the arcane Array.prototype.slice.call for the perhaps equally arcane ...—but at least one is a language feature that takes up less space.

A final point: this curry implementation supports passing more than one argument at a time, which isn’t kosher in the world of pure functional programming. In that world, you need to ensure each function takes one argument at a time—that’s the contract between functions that allows things like compose, pipe et al work. This isn’t a minor point, but curry here works both 1 & >1 argument at a time, so just use it as your concious guides you and you’ll be fine.

Curry away!


Using Dropbox as a Markdown Image Source

Penning a new README. Opening a good Github issue. Answering a Stack Overflow question. Creating a descriptive pull request in Bitbucket. All of these common developer actions and more require the use of embedded images in Markdown documents. Each of these platforms uses a different Markdown flavor, but each support the same general syntax for embedding image URLs inline:

1
![Alt text](https://domain.com/image-name.png)

One of the most common flows for incorporating images into these documents is as follows:

  • Take a screenshot
  • Upload said screenshot
  • Find & copy a URL to the uploaded screenshot
  • Type out the Markdown syntax for inline images and paste in the URL

One of the most common cloud storage services for folks who’ve been using the web for a long time is Dropbox. I fall in that camp so it was incumbent upon me to find an efficient method for executing the above 4 steps in a maximally automated fashion. A method for obtaining a public link to an image in Dropbox and not a link to an HTML page containing the image wasn’t readily apparent to me. Thus in accordance with my principles of sharing technology skills with others the way they’ve been shared with me, I’m posting about it! Here goes:

Steps required to install Dropbox w/ screenshot uploading (happens once)

  • Install the official Dropbox MacOS menu bar app and log in
  • Press the Dropbox icon in the menu bar, opening a drop-down
  • Press the preferences/gear icon in the top right corner of the drop-down
  • Press the Import button at the top of the window that appears
  • Check “Share screenshots using Dropbox” in the Import view

    Steps required for each image

  • Use Shift-Cmd+4 and drag a rectangle around something you want to capture as an image (or Shift-Cmd+3 for the whole screen, or Shift-Cmd+4+Spacebar for one window)
  • Dropbox automatically uploads the screenshot and copies a URL for it to your clipboard (no action is required on your part)
  • Enter ![]() into your document and then paste the URL that was automatically copied to your clipboard in between the parens, creating something like ![](https://www.dropbox.com/s/sosick1984fuzzy/wuzzy.png?dl=0)
  • IMPORTANT: change the 0 at the end of the URL to a 1, e.g. ![](https://www.dropbox.com/s/sosick1984fuzzy/wuzzy.png?dl=1)

That’s it! It’d be even better if we could have Dropbox automatically use 1 & wrap the URL within a Markdown-friendly template. Still, this is already better than manually moving the screenshot into Dropbox & manually creating the link. Hit me up on Twitter if you’ve found a better Dropbox-friendly way to achieve this.


The One Where My Macbook FaceTime HD Camera Joined the Romulan Star Empire

There’ve been many to prognosticate Apple’s fall of late. Few have accurately predicted just how far.

Romulan Warbird

Today, my MacBook (15-inch, 2016) Pro’s built-in FaceTime HD Camera didn’t activate when I began one of what are typically many Google Hangouts in a day. Given my history with Hangouts, I reloaded the page assuming it was a networking or runtime issue with hangouts itself. That failing, I opened up Photo Booth to see something like “No available USB camera devices”. “I must have lost my mind and not realized this newer Macbook doesn’t have a camera”, I thought. But the hardware design synecdoche that is the FaceTime HD Camera was right there. It’d simply disappeared from my system’s recognized internal “USB” devices, rendering remote work-life much more difficult.

A sudden disappearance of this sort has only been recorded in encounters with the Romulan Star Empire, so I catiously moved forward on that hypothesis.

I’d obtained a leak of Section 31 intelligence on Romulan starship network protocols and decided to give some of its incantations a try. BOOM! One of them deactivated the cloaking device and brought the cam back into the fold. I really shouldn’t be telling you this, but here’s the command to run in Terminal or iTerm2:

1
sudo killall VDCAssistant

Next time your MacBook’s camera decide to cloak, run that command first and ask questions later.


IFTTT & the Augmented Human

I’ve been an IFTTT user for a while but only recently have I been trying to use it to its fullest extent. Apps like IFTTT & Zapier are an early version of augmenting ourselves.


A Better Source View in Chrome

JSONView has been one of the first things I ensure is installed in Chrome for years now. It adds interactivity and highlighting whenever you navigate to a JSON resource.
I wanted the same for JS, CSS et al and Sight fit the bill for that. Both extensions add CSS to JSON resources and they were initially conflicting. It turns out that
you can edit the CSS styling for JSONView (and the themes of Sight). By doing so I was able to get them to play nicely with one another.


Programming Kraftwerkflows: git-worktree

git-worktree

git-worktree enables us to manage multiple working trees attached to the same repository. Like most (all?) git-* commands, you interact with it via git worktree rather than git-worktree. I came to know git-worktree via a Google search: “working on 2 git branches at the same time”. Thanks Google!

Why use worktree?

I’m glad you asked that. Most codebases are contributed to by a team. That means plenty of pull requests. Pull requests are important even if you’re not on a team, but you’ll inevitably have more of them when a team is involved. Now PRs are great, but often your teammates cannot review your changes immediately. Does that mean you can pack up and go home to drink clamatos preparados? Maybe, but maybe not.

I want to stay productive even when my PR will be sitting there for a couple days. Sometimes the right way to fill that time is with work on another project, sometimes not. Even when you do need to stay hacking on the same project, you can usually simply checkout another branch get your work done there before moving back to the previous branch when your team starts providing feedback. There is another scenario though, and that’s the scenario in which you want to use git-worktree. In this scenario, your team’s feedback starts trickling in while you’re not at a good stopping point in another branch. You want to essentially work on two branches at the same time. Some folks will just cp -r repo repo_2 in this scenario. Those folks might wonder why that’s no good enough. The reasons are profound but quite simple to understand. There are essentially 2:

  1. Copying a large project takes a long time. In a plain cp -r execution, there’s at least two things happening that are unnecessary and take the bulk of that time.
    1. Copying all of node_modules. Using git-worktree in concert w/ a symbolic link can be better here.
    2. Copying all of your git history. git-worktree doesn’t do this.
  2. When you cp -r you’re more likely to end up with the two folders out of sync in a serious way. This isn’t merely anecdotal—git-worktree keep your remotes etc. in sync

How to use it

First, you need to have git 2.5+. Before becoming interested in using git-worktree I was using git 2.2. I simple brew upgrade git gave me git 2.9 and it’s working great! git worktree add ../ignite_002 master will create a new folder named ignite_002 and set it’s head to master, as long as you’re not already on master.

Conclusion

I’m new to git-worktree, but so far I’m finding it a useful workflow upgrade that I’ll apply in a limited set of situations. It represents the biggest improvement to my git workflow in months.
If I’ve piqued your interest, read on:

Cheers and happy Kraftwerking my fellow Gitlians!


Nightwatch Parlance

Nightwatch has its own little semantic world. It’s a world that, while not “on fleek”, makes a lot of sense to me. In a teamgramming context I add a gang of comments if introducing new tech or use thereof. In introducing a new type of UI test to a project at Netflix, I decided to explain some of the Nightwatch parlance. I’ve transposed some of that here for y’all.

Elements

Elements start with an @ and allow you to have improved semantics within a Nightwatch test context. CSS selectors are typical either more verbose or more terse than elements in Nightwatch parlance.

Commands

Commands give you the ability to extend the Nightwatch API w/ your own methods.

Tags

Tags allow you to flexibly group your tests according to your own organization principles, allowing you to execute subsets of all tests.
Within a spec it looks like this:

1
2
3
4
5
6
function createNotepadTestRunner () { }
module.exports = {
tags: [ 'sanity', 'ancillary' ],
NotepadTest: createNotepadTestRunner()
}

An example of leveraging this in concert w/ NPM scripts:

1
2
3
4
5
6
{
"scripts": {
"test:ancillary": "npm t -- --tag ancillary",
"test": "nightwatch -c ./config/nightwatch.js --env chrome"
}
}

Web driver

A web driver is a piece of software that allows you to manipulate a website using the web client’s native interface. Selenium is the web driver, written in Java, that Nightwatch provides a beautiful JavaScript API for. Nightwatch supports most everything Selenium does. It also achieves the remarkable feat of being familiar to both Selenium devs new to JavaScript and JavaScript devs unfamiliar w/ Selenium.


Hating on simplicity: A developer's passion?

It’s common to see talented engineers shit on egalitarian software solutions only because they’re not perfect for them.

That mentality is both socially and technically toxic in a larger successful company that writes enduring software.

There’s a great benefit + beauty in having a very simple system that’s easy to replicate and update—easy to propagate technically & socially—but it’s tough to love simplicity with a belief system that rewards complexity.