How to setup ESLint for your next project

how to setup ESLint for your next project nickang blog banner
Photo by Norbert Levajsics on Unsplash

For over a year, I used ESLint at work without knowing. I didn’t have to understand what package exactly was doing the work of linting – it just worked, quietly doing its duty of enforcing no unused variables and imports, keeping consistent code styles, and all that nice stuff.

But I recently had to learn how to set it up for a project I’m working on on the side – a little concept game unpretentiously called the Object Oriented Ice Cream Shop Game. The name is fortunately temporary until I find a more original name. Among other things, one of the reasons I wanted to do a side project was to learn from linter rules of my own choosing. Quick detour about that, then we’ll cover how to setup ESLint for your project.

Learning from linter rules

I’ll write a full post dedicated to this idea, but in short: I believe it’s possible to learn a ton about programming from the linter warnings that frantically wave at you as you code. And I’m not just talking about language-specific learning points – I’m talking programming in general.

For example, I learned that having trailing commas when writing object or array literals is a good idea because it provides cleaner git diffs. That’s not something I can confidently say I’d have considered until it was made clear to me when my linter underlined it in red and I clicked through on its associated comma-dangle rule on ESLint:

comma dangle eslint linter warning

Nuff’ said. Let’s move on to how to setup ESLint for your next project.

How to setup ESLint

Setting up ESLint for a project is actually relatively pain-free.

First, let’s state one of the most important and often overlooked pieces of information you’ll need to setup ESLint:

There’s ESLint the npm package, and then there’s the ESLint code editor package for Atom/Sublime/etc.

You will need to install both to get ESLint to work as you code. If you install only the ESLint npm package, you will need to run this command every time you want to check your code:

That’s obviously not as powerful as having an omni-present code police.

Here are the steps to setup ESLint for your project:

  1. Run npm install --save-dev eslint to save package to your project’s node_modules folder and have it listed in package.json under devDependencies
  2. Create a .eslintrc.js file in your project root directory for configuring project-specific linter rules (alternatively, run node_modules/.bin/eslint --init to use ESLint’s interactive configuration file generator)
  3. Install the ESLint package for your code editor (Atom | Sublime)
  4. Configure ESLint to your needs, installing additional ESLint plugins for specific rules and style guides (eg. eslint-config-airbnb-base for Airbnb’s), and for libraries (eg. eslint-plugin-jest for Jest testing library)

Configuring .eslintrc

Here is an example of my .eslintrc.js file. Note that I chose to use the .js file format, but you can choose .yml and .json and use slightly different syntax.

With that, you’ll have setup ESLint for your project!

One last point before you go.

ESLint is for ES

One of the reasons I got confused was the fact that there are other linters out there.

Taking a quick look at the code editor packages I have installed shows me 5 different packages:

  • linter
  • linter-ui-default
  • linter-js-standard (for JavaScript)
  • linter-rubocop (for Ruby)
  • linter-sass-lint (for Sass)

If I’m not wrong, the first two are mandatory for setting up a linter mechanism in my code editor (currently using Atom). The last two are for different programming languages.

But the third, linter-js-standard, is for JavaScript! Wouldn’t this conflict with ESLint?

I’m glad you asked because it means you noticed that ESLint is for ES – as in, ECMAScript, or more popularly, JavaScript. ESLint is a specific linter software that comes bundled with a default set of rules for JavaScript.

This is my 6th linter package:

  • linter-eslint (to use ESLint to lint JavaScript)

ESLint is project-specific and I believe has become the de-facto standard tool for linting JavaScript. So when your project has ESLint set up, its code will be linted with ESLint and not the other JavaScript linters.

In fact, the linter-js-standard package has a settings option specifically for making this explicit:

linter js standard setup ESLint

Ok, I think that’s all the linter know-how any of us needs to get up and running.

Now just write code and trust that your linter’s got your back. You should, of course, verify that it’s actually working by deliberately making an obvious mistake… but you already knew that.

Happy days ahead!


Like posts like these? Subscribe to my newsletter to get more useful posts delivered once a month to your email.



How to clone class instance in JavaScript

One very common scenario for wanting to clone a class instance is inside a function.

Why there’s a need to clone objects/arrays inside functions

Because non-primitive data structures are passed by reference in JavaScript, we will inadvertently mutate the original object or array passed into a function as an argument. Here’s a quick illustration of this behaviour:

In the above, userJohn was mutated inside the maskSensitiveInfo() function. Specifically, the line user[field] = 'hidden'; mutates userJohn directly instead of mutating a copy of it.

This behaviour is expected for non-primitive data types; that is, any variables that hold a data type other than the 6 primitives (boolean, number, string, symbol, null, and undefined).

I think it’s also the reason why many JavaScript code style guides I’ve come across so far recommend not mutating arguments within functions. Airbnb’s style guide is an example.

How to shallow copy an object

Instead, they recommend creating a copy of any object/array inside functions – basically as a preventive measure to eliminate the potential for unwanted (and hard to trace) side effects caused by mutating something outside of the function from within.

In the above snippet, the maskSensitiveInfo() function now creates a copy of the user object being passed in and uses it for intermediate steps that mutate it, before returning it. That’s why userJohnMasked is no longer the same object as userJohn (ie. userJohnMasked === userJohn evaluates to false).

Caveat for shallow copy: only one level deep

What we’ve just seen is shallow copying. It’s so-called “shallow” because Object.assign() is only going to copy over the first-level values and assign that to a new object. If, for example, userJohn has a key called “account” and its value is another object, that object is not copied but is once again only referenced.

This snippet illustrates the point:

The original object, userJohn, is accidentally mutated by the line userClone.account.number = 'hidden'. This is one of those horrible bugs that can be really hard to pinpoint.

To do a deep copy (vis-a-vis shallow copy), it’s best to use an external library like jQuery or Lodash:

More details on deep cloning can be found in this SO thread.

So that’s how you shallow/deep clone objects created from using the object literal syntax var x = {}; or var x = Object.create();, meaning they are literally constructed directly from the Object class in JavaScript.

What about objects that are instances of a custom implemented class? As we’ll see, because we will most likely have methods implemented on custom classes, the methods above will not suffice – the instance methods will not be copied over!

Cloning a class instance including its methods

I recently found out something that wasn’t obvious to me – apparently, methods defined within a class definition are automatically added to the prototype chain of the instance object.

So, to copy over the methods from one class instance to another, we will need to copy the prototype chain on top of copying the instance variables.

Here’s the magical series of built-in methods that can be used to create a copy of an instance of a custom-implemented class:

That’s quite horrid syntax on first and second glance, but on third glance…

Here’s how it works:

  1. Object.create() creates a new object and Object.getPrototypeOf() gets the prototype chain of the original instance and adds them to the newly created object
  2. Object.assign() does as we’ve seen earlier, which is to (shallow) copy the instance variables over to the newly created object

This comes in really handy for custom-implemented classes like Stack or Queue or LinkedList.

However, sometimes you will need to add a few extra lines to the copyInstance() method, depending on whether your class has any instance variables that need to be copied as well. In my case, I had to clone an array that is stored as an instance variable called this.stack within the Stack implementation:

Here’s the use case I recently had with a Stack (it uses ES6, so in case you’re unfamiliar, just treat all const and let as vars):

Summary

I didn’t intend for this post to get so long, but I wanted to be complete with my examples because I know it’s important contextual information for wrapping your head around the idea of cloning.

Here’s a summary to make it easier:

  • Non-primitive data types like Objects and Arrays are passed by reference into functions, unlike for primitives which are passed by value
  • Passed by reference implies that if a function mutates or reassigns an argument that is an object or array, the original variable outside of the function also gets mutated/reassigned – this can become a nasty, hard to uncover bug
  • For the above reasons, Airbnb, among other companies, eschew direct mutation or reassignment of arguments within functions
  • The solution is to create a clone before working with the cloned variable inside the function to prevent side effects
  • There are two types of cloning: shallow and deep
  • Shallow only clones one layer deep, which means if any key-value pair in an object contains another object, or if an object is stored as an item in an array, those continue to be references instead of cloned values
  • Deep cloning accounts for nested objects by effectively creating copies recursively until the deepest layer, ensuring there are no connected references to the original object
  • To clone an instance of a custom-implemented class, including its custom-implemented methods within the class, you need to copy over the prototype chain (because methods defined inside a class are added to the prototype chain) as well as the instance variables

I’m mainly writing this to ensure I have a note on this esoteric but essential part of JavaScript, but I certainly hope it was helpful to you in some way too!


Enjoyed reading this? I’ve been writing posts like these revolving around technology, society, and life on and off for more than a year now. This year I’m aiming for 5 posts per week, and I’d love to have you join me on that personal journey. You can read more at my blog or subscribe to get the most interesting posts delivered to your inbox – it’s free.

What to do when your bike runs out of fuel

bike motorcycle
Photo by Les Anderson

Hello, friend. If you’re here for an actual guide on what to do when your bike runs out of fuel, skip ahead to the “What to do when your bike runs out of fuel” section below. I’ll be recounting my own experience today first in the proceeding section.

Today after knocking off from work, I hopped on my Honda Shadow 400 and rode away from the office. I was ready to go home to my wife and dog after a long day at work.

Three minutes into the 30 minutes journey though, I noticed my engine getting softer… and I immediately knew that it was running out of fuel. My eyebrows grew heavy.

Continue reading “What to do when your bike runs out of fuel”

How to prevent jQuery from loading image in parseHTML

This post is inspired by a recent bug fix at work related to jQuery’s parseHTML() method.

I noticed multiple redundant calls to our server endpoint each time a user saves an email template using the drag-and-drop email builder of Metisa.

The bug, when traced to its end, was nothing like what I’d originally suspected. Because we use Backbone.js for the front-end model layer (to make API calls) with React.js as the front-end view layer, I had initially thought it was Backbone making redundant API calls.

Continue reading “How to prevent jQuery from loading image in parseHTML”

Binary Search explained

binary search blog banner nickang
Photo by Pablo Garcia SaldaƱa on Unsplash

If you’re a software engineer, you’ve probably heard about binary search before. And if you don’t know what it is, how it’s implemented, and its strengths and weaknesses, this post is for you.

Binary search is, as its name suggests, a search algorithm. In fact, it’s one of the most efficient and commonly used search algorithms.

Continue reading “Binary Search explained”

How to implement a Linked List in JavaScript

implement linked list in javascript banner nickang
Photo by LinkedIn Sales Navigator on Unsplash

In this post, you’ll learn how to implement a linked list in JavaScript. This is the second part of a 2-parter post on linked lists (read part 1).

Let’s jump right in!

Continue reading “How to implement a Linked List in JavaScript”

How to start using the command line (part 2)

BSP how to start using the command line nickang blog
Photo by Dan Edwards on Unsplash

Welcome to the second part of How to start using the command line. You can read part 1 here if you haven’t already – I cover the most basic commands there to get you started.

In this second part, I’ll go through a few more basic commands and introduce the concept of a flag that you can use to modify certain commands. A flag can, for example, be used to modify the command rm to act on a directory instead of a file.

Let’s dive in!

Continue reading “How to start using the command line (part 2)”