As we learned in our last post, static analysis is useful in various situations, whether that’s keeping a codebase consistent, catching potential performance issues, or rewriting code to be more idiomatic. In our previous post, we used PMD to analyze Apex code. In this post, however, we’ll consider how to analyze another Salesforce programming environment: Lighting Web Components.
Salesforce developed Lightning Web Components (LWC) as a fast, enterprise-grade wrapper around vanilla web components. LWC is built on the same HTML, CSS, and JavaScript that powers the web, so any analyzer for those languages can be applied here.
In this post, we’ll integrate ESLint with your LWC project. We’ll also learn how to integrate ESLint with your editor and your CI system, just like we did with PMD.
Before getting started, you should have a relatively recent version of Node installed. Some familiarity with JavaScript can also help, but it’s not essential. We’ll also be using VS Code for this tutorial.
We’ll start by cloning our sample LWC project from this Git repository: https://github.com/gjtorikian/sfdc-linting
This repository is a forked copy of the dreamhouse-lwc project, except it has (intentionally) introduced some errors. We’ll use this to demonstrate how ESLint works.
Run npm install
to download the project’s dependencies. ESLint is among them, but you’re also getting LWC specific ESLint plugins. We’ll go into more details on these below!
The custom LWC components in this repo are stored in the force-app/main/default/lwc
directory. When you open this up, you’ll see several directories, each representing a single component, with their own HTML and JavaScript files.
Since JavaScript is an interpreted—rather than compiled—language, there’s no inherent way to validate whether a code path is correct until it’s executed. With Apex, Kotlin, C, or other compiled languages, a compiler steps in to ensure that all of your code adheres to the language’s grammatical rules. With JavaScript, Ruby, Python, or other interpreted languages, you often won’t know whether something is valid until a user encounters it.
This is why a static analyzer is crucial for these interpreted languages. To demonstrate their power, let’s run ESLint and see what happens. For this project, ESLint has already been configured as an npm script, so we don’t need to do any configuration to run it. In the directory where you cloned your project, type this line at the command prompt:
npm run lint
You should see the following output:
> [email protected] lint
> eslint **/{lwc,aura}/**/*.js
dreamhouse-lwc/force-app/main/default/lwc/daysOnMarket/daysOnMarket.js
39:22 error Parsing error: Unexpected token, expected "(" (39:22)
dreamhouse-lwc/force-app/main/default/lwc/propertyTile/propertyTile.js
7:15 error 'selectedEvent' is assigned a value but never used no-unused-vars
✖ 2 problems (2 errors, 0 warnings)
The second error is similar to what we saw in our Apex project: a variable was created, but unused. However, the first error is much more nefarious. If you open the daysOnMarket/daysOnMarket.js
file and navigate to line 39, you’ll notice that the final conditional is incorrectly marked as else if
, when it should simply be else
:
if (this.daysOnMarket < MAX_DAYS_NORMAL_STATUS) {
this.status = 'normal'
} else if (this.daysOnMarket < MAX_DAYS_WARNING_STATUS) {
this.status = 'warning'
} else if {
this.status = 'alert'
}
Catching this kind of error in a unit test is not guaranteed. This is the kind of subtle JavaScript bug that a static analyzer is perfectly designed for capturing and reporting on.
ESLint rule configuration is similar to that of PMD. The main difference is that ESLint uses JSON notation instead of XML. Open the file at force-app/main/default/lwc/.eslintrc.json
to see how these rules are defined. Right at the top, you’ll see a line that reads:
"extends": ["@salesforce/eslint-config-lwc/recommended", "prettier"],
Here, our ruleset is extending the @salesforce/eslint-config-lwc
package we installed earlier. Our project also has the option of adding new rules or inheriting from any other npm package which has ESLint rules configured.
Rather than running ESLint on the command line, let’s integrate it directly into the editor. This allows us to get immediate feedback on the code as it’s being written, without switching back and forth between the terminal.
There’s a plugin for VS Code that brings ESLint right into the editor. When you visit that page and click Install, this downloads and installs the plugin to your editor.
Return to the daysOnMarket.js
file. You’ll notice that the previously offending else if
line now has a red, squiggly line underneath it. If you place your mouse cursor over it, a dialog box pops open that shows the error message from ESLint:
At this point, you’ve seen how ESLint runs across your entire project and how it can be applied to individual files in your editor. The final location for integrating ESLint exists within your CI test suite. Just as your test suite fully tests your application’s logic, your static analyzer should also run across your code to identify any potential errors or issues.
Since ESLint is a dependency installed through npm, your CI servers don’t need any additional configuration to support it. If you’re using GitHub Actions, you can just add a separate step in your actions YAML file to run the program, just as you do on the command line:
name: CI
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install modules
run: npm install
- name: Run ESLint
Run: npm run lint
If you’re not using GitHub actions, you can simply run ESLint within a script:
#!/bin/sh
set -e
npm run lint
Since ESLint fails with a non-zero status, running this script will mark your CI as a failure, too, if there are any issues.
In this series, we’ve taken a broad look at how static analysis helps keep your code clean, consistent, and effective. Static analysis can help catch those smaller problems that might get overlooked in a code review, making it an ideal component in your software development toolchain. By integrating a tool such as ESLint into your CI test suite, you can be sure that future changes won’t introduce any undesirable effects.
For learning more about working with LWC, Salesforce has Trailhead badges on various topics. The ESLint website also provides some more information on the philosophy and goals of the project. If you’d like to explore more about how to bring Salesforce together with VS Code, there’s a whole suite of tools that can be installed as plugins to make writing code much easier!
Also Published Here