Static Analysis of JavaScript applications with SonarQube
Static analysis helps developers to write a cleaner and safer code. It can catch bugs, fix vulnerabilities, analyze the quality of your code, and check the security. As a team leader at First Line Outsourcing, I responsible for code quality, stability, and safety.
In this article, we will look at one of the tools for performing static code analysis — SonarQube and how to set up it for JavaScript applications.
Requirements
I will use a simple Node.js TypeScript application as an example, but you can use any of your existing JavaScript applications either Angular, React, Vue, etc.
Introduction
SonarQube is the automatic static code analysis tool that detects bugs, vulnerabilities, and code smells. It supports 27 languages including JavaScript and TypeScript. This tool can be easily integrated into your existing workflow to enable continuous code inspection across your project branches and pull requests. The tutorial will show you how to run static analysis locally in order to fix your issues before code review or testing.
Installation
You can download the free community version of SonarQube on your machine or use a Docker container.
docker-compose.yml
version: '3'
services:
sonarqube:
image: sonarqube:latest
ports:
- '9000:9000'
- '9092:9092'
Use these commands to start or stop the container:
docker-compose -f docker-compose.yml up -d
docker-compose -f docker-compose.yml down
After the start, you can open the WEB application on http://localhost:9000. Use admin/admin credentials to log in.
Set up project
First of all, you should create a configuration file in the root directory of your project.
sonar-project.properties
sonar.projectKey=name-of-the-project
sonar.projectName=name-of-the-project
sonar.projectVersion=1.0
sonar.language=ts
sonar.sources=src
sonar.sourceEncoding=UTF-8
sonar.exclusions=src/**/*.test.ts sonar.test.inclusions=src/**/*.test.ts sonar.coverage.exclusions=src/**/*.test.ts,src/**/*.mock.ts,node_modules/*,coverage/lcov-report/* sonar.javascript.lcov.reportPaths=coverage/lcov.info sonar.testExecutionReportPaths=coverage/test-reporter.xml
You can use js as sonar.language, and *.js extension for all files.
Install sonarqube-scanner in order to have the possibility to start the analysis.
npm install --save-dev sonarqube-scanner
Also, add the script to the root directory of your project.
sonar-project.js
const sonarqubeScanner = require('sonarqube-scanner');sonarqubeScanner(
{
serverUrl: process.env.SONAR_SERVER || 'http://localhost:9000',
token: process.env.SONAR_TOKEN || '',
options: {}
},
() => process.exit()
);
So now you can start the analysis using the command node sonar-project.js.
This script starts the analysis asynchronously and doesn’t wait for the result. That means it can’t be used for your CI/CD solutions. But the script is good enough for starting locally.
If you are going to integrate SonarQube to your CI/CD workflow, you can use sonarqube-verify.
npm install --save-dev sonarqube-verify
package.json
{
...
"scripts": {
...
"sonarqube-verify": "sonarqube-verify"
}
}
This library waits for the result and PASS or FAIL the job. Also, it can send the report to the remote server with SonarQube installed if you want to integrate it into your CI/CD solutions.
Examples
Let’s start the analysis for the empty project and see how it looks like in WEB application.
Because it doesn’t have any issues, SonarQube marks it as PASSED. Let’s imitate some issues and see the result.
The function below uses Array.map(…) method but doesn’t handle the result. It means that Array.map(…) can be replaced to Array.forEach(…) and the code won’t create a useless array and use extra storage space.
export function example1() {
const array = [1, 2, 3];array.map(console.log);
return array;
}
After restarting the analysis, we can see that our project is marked as FAILED.
SonarQube calculates the status according to the number of issues and the size of the project. Because of the small size of our project, this simple issue leads to the FAILED status.
My favorite part of this static analysis tool is how it shows your issues and explains why you see them, for example:
Now let’s imitate a code smell example. The function below uses the same name twice. It’s a bad code style practice.
export function example2() {
const number = [1, 2, 3];number.forEach(number => console.log(number));
}
On the screenshots, we see that we have a code smell issue and the reason of the issue occurring.
Tips
- Static code analysis can help you to keep your code clean and safe
- It’s easy to integrate static code analysis tools like SonarQube into your projects
- It can be integrated into your CI/CD solutions
- SonarQube reports can show the test coverage, you just need to run tests before analysis and turn on the coverage flag
Conclusion
You have now learned about static code analysis and how to set up one of the tools that provide this functionality — SonarQube. Here you can find the example from the article. We at First Line Outsourcing use it as the instrument which helps us to keep the quality of our code at a high level.