When writing code, it’s a good idea to use a code linting tool for several reasons: it identifies possible errors, enforces a clear coding style, and prevents engineers from using antipatterns. Linting tools are able to achieve all this without actually running your code or caring about what it does. This is particularly important for JavaScript, since any errors in the code would otherwise only be caught at runtime, and might reach the users.
Here at Wix we use ESLint for JavaScript because it’s highly configurable and extensible. You can choose not to run some rules and not to fail on some errors, and you can even create your own rules via ESLint plugins, which is exactly what we have done. In this post I’ll explain why we wrote an ESLint plugin, as well as how to structure and test the rules.
Using Lodash, in Style
We got the idea to write an ESLint plugin for Lodash while we were upgrading some of our projects to the latest major version of Lodash (version 3). Some changes in Lodash were not backward-compatible, which forced us to make changes in our code. In the process, we reviewed our usage of Lodash and encountered code that, while valid, was muddled and unclear.
Here’s a contrived example that demonstrates such unclear code:
Other than fixing some basic style issues, this particular plugin enables developers to get to know some of the less-trivial methods and finer points of Lodash, such as using the _.invoke method, and which methods end an implicit Lodash chain.
Writing an ESLint Plugin
ESLint makes writing and testing rules really easy. To start, you can look at an existing plugin or use the Yeoman generator that the ESLint project recommends.
Structuring a Rule
The rules themselves are tree-visitors over each script file’s Abstract Syntax Tree (AST), so we found it easiest to use Esprima’s Online Parser to check our code samples’ structure.
A rule’s structure looks something like this:
Here’s an example of an ESLint violation report statement:Each rule’s implementation is a Node.js module that exports a function. The function itself gets the context (through which we report errors and get additional data) and returns an object that adds visitors to the AST traversal. The object has a key for each node type that’s significant for the rule, as well as another visitor upon “exiting” that node (after visiting all its children). In some visits, under certain conditions, the code should report an ESLint violation. Each violation is reported on a specific node, with a templated string as the message. Variables are enclosed in double curly braces, {{ }}.
context.report(node, ‘Do not use .value() after chain-ending method {{method}}’, {method: method});
As for testing, ESLint’s Rule Tester makes it natural to write the rules in a TDD style: The tester simply runs against some samples of invalid code and some samples of valid code. With the correct test cases, it’s easy to get 100% code coverage over all possible branches of code.Testing the Rules
Try It Out
For actual samples of both rules and tests, check out the open-sourced code for our plugin, and see just how easy it is to use ESLint plugins to make sure your shared code is up to snuff. You can also write your own ESLint plugins or contribute to ours!