Hackernoon logoUsing ESLint for Encapsulation by@abdulnimeri

Using ESLint for Encapsulation

Abdul Nimeri Hacker Noon profile picture

@abdulnimeriAbdul Nimeri

Linters may not be as powerful as compilers — since they can’t add new language features — but they’re pretty good at taking away features. And sometimes, taking away features can be just as powerful as adding them.

This observation is especially true when we talk about encapsulation. Encapsulation is about information hiding, aka taking away information. A lot of encapsulation features are implemented at the language level, such as function scoping and module scoping. But when we want even more encapsulation than what the language provides, linters are a good fit to take over.

Let’s look at some examples where ESLint provides us with encapsulation even while ES6 provides none.

Encapsulating the Browser API

If you need to support server-side rendering, then you’ll have to make sure that your code can run in a server environment, where there won’t be any browser-specific global variables like window, location, etc. Thankfully, ESLint allows us to configure the global variables for a given file:

ReactDOM.render(
<App />,
document.getElementById('root')
); // flagged by linter

/* eslint-env browser */
ReactDOM.render(
<App />,
document.getElementById('root')
); // good to go!

This way, we can hide the browser API from all modules, except the specific modules that need them. We can do the same for other environments too!

Encapsulating Modules

Let’s say that we want to centralize all network requests in our codebase to one file called api.js. We’re probably using a single networking client for this, like Axios for example. We can enforce this by making sure that no one in the codebase can import Axios except for our api.js file.

We’ll use the no-restricted-modules lint rule to disallow other modules from importing Axios by adding this to our .eslintrc:

{
"no-restricted-modules": ["error", "axios"]
}

and then disable it just for our api.js file:

This way, we can hide networking functionality from all modules, except the specific modules we whitelist.

Encapsulating Classes

Let’s say we want a private method in our Javascript class. Unfortunately, there’s no private keyword for us to use for enforcing this rule, but we can use ESLint’s no-underscore-dangle rule to a similar effect:

class MyClass {
_myPrivateMethod() {}

myPublicMethod() {}
}
const instance = MyClass()
instance._myPrivateMethod(); // flagged by linter

Lint Rules are Traffic cones

All of the above encapsulations are easy to break. Static analysis tools like linters can’t protect against dynamic language features like require('axios'), or instance['_myPrivateMethod'](), and that’s fine. Lint rules are more like traffic cones than concrete walls.

The idea isn’t to guard against willful violations of these rules. It’s to align the path of least resistance with best practices, and that’s usually good enough.

Hacker Noon is how hackers start their afternoons. We’re a part of the @AMIfamily. We are now accepting submissions and happy to discuss advertising &sponsorship opportunities.
To learn more, read our about page, like/message us on Facebook, or simply, tweet/DM @HackerNoon.
If you enjoyed this story, we recommend reading our latest tech stories and trending tech stories. Until next time, don’t take the realities of the world for granted!

Tags

Join Hacker Noon

Create your free account to unlock your custom reading experience.