DeepSource JavaScript analyzer lands in beta
DeepSource now supports JavaScript, React and TypeScript, with 470+ types of issues.
- By Siddhant
- ·
- Product
- Releases
When writing code, it's hardly sometimes that our code executes successfully in the first run. And then, after every execution failure of the code, we dive into the error log to find where the bug resides. Unfortunately, we end up spending more time on resolving bugs than what is actually needed. And this has been really common in the case of JavaScript.
As developers, we ensure code quality with the help of unit and functional testing. We can complement these test plans with static analysis through which we can now check the code before its execution to assess its quality and its adherence to coding standards. Static analysis helps us find the issues in our code that we humans can’t always spot by ourselves and thus, ensures code quality throughout the project along with maintaining developer efficiency.
Today, we are really excited to launch continuous static analysis for JavaScript, detecting 470+ issues, like bug risks, anti-patterns, performance and style issues.
Supported Frameworks and Language Standards
- All the versions of ECMAScript (ES3, ES5, ES2015 - ES2020)
- React JSX
- TypeScript
- All major module systems ( CommonJS, ES modules and AMD)
- Popular JavaScript style guides (Airbnb, Google and Standard)
ESLint Rules & Plugins
DeepSource JavaScript analyzer fully supports all the ESLint core JavaScript rules and is 100% ESLint compatible. Along with that, it currently supports the following ESLint plugins :
- Node.js
- TypeScript
- React
We are working to add support for more plugins in order to improve the analysis further.
Using the JavaScript analyzer
To start analyzing your JavaScript code, create an account on DeepSource, enable the javascript
analyzer in your .deepsource.toml
file, and activate analysis.
Sample Configuration (.deepsource.toml)
version = 1
test_patterns = ["*/test/**"]
exclude_patterns = [
"public/**,",
"dist/**"
]
[[analyzers]]
name = "javascript"
enabled = true
[analyzers.meta]
ecma_version = "2016"
module_system = "commonjs"
environment = [
"nodejs",
"browser",
"jest",
]
plugins = ["react"]
style_guide = "airbnb"
dialect = "typescript"
Here’s a few issues detected by the analyzer:
Bug-risks
- Debugger should not be used in production code
Thedebugger
statement is used to tell the executing JavaScript environment to stop execution and start up a debugger at the current point in the code. Having
it in the production code can stop the browser from executing code and opens an appropriate debugger.
Example :function isTruthy(x) { debugger return Boolean(x) }
- Prevent reassigning function declarations
Overwriting/Reassigning a function is often indicative of a mistake or issue. It can cause bugs in the code at runtime.
Example :function foo() {} foo = bar function foo() { foo = bar }
- Using constant condition in conditional statements
A constant expression (for example, a literal) as a test condition might be a typo or development trigger for a specific behavior. It may break the code during the runtime.
Example :if (false) { doSomethingUnfinished() } if (void x) { doSomethingUnfinished() } do { doSomethingForever() } while ((x = -1))
Anti-patterns
- Prefer the usage of
===
and!==
instead of==
and!=
It is considered good practice to use the type-safe equality operators===
and!==
instead of their regular counterparts==
and!=
. For instance, these statements which ideally should be false are
considered true :[] == false [] == ![] 3 == "03"
- Prevent the usage of
alert
JavaScript'salert
,confirm
, andprompt
functions are widely considered to be obtrusive as UI elements and should not be used in production code. They should be replaced by a custom implementation.
Example :alert("here!"); confirm("Are you sure?"); prompt("What's your name?", "John Doe"); should be replaced by - customalert("here!") customconfirm("Are you sure?") customprompt("What's your name?", "John Doe")
- Prevent the usage of
new
for Side Effects
We usenew
with a constructor to create an object of a particular type and store that object in a variable, such as:var car = new Car();
It is of no use to usenew
like this :new Car();
In this case, the created object is thrown away because its reference isn't stored anywhere
Security
- Prevent the usage of
eval
JavaScript'seval()
function is potentially dangerous and is often misused. Usingeval()
on untrusted code can open a program up to several different injection attacks. The use ofeval()
in most contexts can be substituted for a better, alternative approach to a problem.
Example :var obj = { x: 'foo' }, key = 'x', value = eval('obj.' + key)
- Prevent the usage of Script URLs
Using javascript: URLs is considered by some as a form ofeval
. Code passed in javascript: URLs has to be parsed and evaluated by the browser in the same way thateval
is processed. Also, assembling javascript: URLs (or other strings that contain source code) is a tricky task which is prone to XSS vulnerabilities.
Example :location.href = 'javascript:void(0)'
- Prevent the usage of
implied-eval
Try to eliminate impliedeval()
through the use ofsetTimeout()
,setInterval()
orexecScript()
. As such, it will warn when either function is used with a string as the first argument.
Example :setTimeout("alert('Hi!');", 100); setInterval("alert('Hi!');", 100); execScript("alert('Hi!')"); can be replaced by : setTimeout(function() { alert("Hi!"); }, 100); setInterval(function() { alert("Hi!"); }, 100);
Performance
- Detect unreachable code after
return
,throw
,continue
, andbreak
statements
Because thereturn
,throw
,break
, andcontinue
statements unconditionally exit a block of code, any statements after them cannot be executed. Detecting and removing them helps to improve the performance of the code.function hello() { let x = 3 return x x = 5. // Never executed console.log(x). // Never executed }
- Detect the unused variables
Variables that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. Such variables take up space in the code and cause confusion.
Example :// x is declared but is never used var x var i for (i = 1; i <= 100; i++) { console.log('Hello') }
- Detect empty function declarations and block statements
Empty functions can reduce readability and also end up taking up space which is of no use. Empty block statements, while not technically errors, usually occur due to refactoring that wasn't completed. They can cause confusion when reading code and can affect the performance too.
Example :function foo() {} var foo = function () {} var foo = () => {} if (foo) { } while (foo) {}
Upcoming releases
We're continuously improving the analyzer and here's a near future roadmap:
- Add support for Angular, Flow, Vue and other popular frameworks.
- Autofix support for commonly occurred issues.
- Automated code formatting support for Prettier and Standard JS.
We’re very excited about this release, and hope that this will help you prevent issues in your code, and make writing JavaScript even more fun! Head over to the docs or tell us what you think; Feedback/suggestions/bugs - discuss.deepsource.io