在编写代码时,我们的代码在第一次运行时几乎没有成功执行的时候。然后,在代码的每一次执行失败后,我们都会潜入错误日志中去寻找错误所在。不幸的是,我们最终在解决错误上花费的时间比实际需要的时间要多。而这在JavaScript的案例中真的很常见。
作为开发人员,我们在单元和功能测试的帮助下确保代码质量。我们可以用静态分析来补充这些测试计划,通过静态分析,我们现在可以在执行之前检查代码,以评估其质量和对编码标准的遵守。静态分析可以帮助我们发现我们人类自己无法发现的代码问题,从而确保整个项目的代码质量,并保持开发人员的效率。
今天,我们非常高兴地推出了对JavaScript的连续静态分析,检测470多个问题,如bug风险、反模式、性能和风格问题。

支持的框架和语言标准
- 所有版本的ECMAScript (ES3, ES5, ES2015 - ES2020)
- React JSX
- TypeScript
- 所有主要的模块系统(CommonJS、ES模块和AMD)。
- 流行的JavaScript风格指南(Airbnb,谷歌和标准)。
ESLint规则和插件
DeepSource JavaScript 分析器完全支持所有 ESLint 核心 JavaScript 规则,并且 100% 兼容 ESLint。除此之外,它目前还支持以下ESLint插件。
我们正在努力增加对更多插件的支持,以进一步提高分析能力。
使用JavaScript分析器
要开始分析你的JavaScript代码,在DeepSource上创建一个账户,在你的.deepsource.toml 文件中启用javascript 分析器,并激活分析。
配置样本(.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"
下面是分析器检测到的一些问题。
错误-风险
-
调试器不应该在生产代码中使用
debugger语句是用来告诉执行的JavaScript环境停止执行,并在代码的当前点启动调试器。在生产代码中使用它在生产代码中可以阻止浏览器执行代码,并打开一个适当的调试器。
例子:
function isTruthy(x) { debugger return Boolean(x) } -
防止重新分配函数声明
重写/重赋一个函数往往表明了一个错误或问题。它可以在运行时引起代码的bug。
例子:
function foo() {} foo = bar function foo() { foo = bar } -
在条件语句中使用常量条件
一个常量表达式(例如,一个字面意思)作为测试条件,可能是一个打字错误或开发触发的特定行为。它可能会在运行时破坏代码。
例子:
if (false) { doSomethingUnfinished() } if (void x) { doSomethingUnfinished() } do { doSomethingForever() } while ((x = -1))
反模式
-
倾向于使用
===和!==而不是==和!=使用类型安全的平等运算符
===和!==,而不是普通的对应运算符==和!=,被认为是很好的做法。例如,这些在理想情况下应该是假的语句 被认为是真的。 -
防止使用
alertJavaScript的
alert,confirm, 和prompt函数被广泛认为是碍眼的UI元素,不应该在生产代码中使用。它们应该被一个自定义的实现所取代。例子:
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") -
防止使用
new的副作用我们在构造函数中使用
new,以创建一个特定类型的对象,并将该对象存储在一个变量中,例如:var car = new Car();像这样使用
new是没有用的:new Car();在这种情况下,创建的对象会被扔掉,因为它的引用没有存储在任何地方。
安全性
-
防止使用
evalJavaScript的
eval()函数具有潜在的危险性,经常被滥用。在不受信任的代码上使用eval(),会使程序受到几种不同的注入攻击。在大多数情况下,使用eval(),可以用更好的、替代性的方法来解决一个问题。例子:
var obj = { x: 'foo' }, key = 'x', value = eval('obj.' + key) -
防止使用脚本URLs
使用javascript。URLs被一些人认为是一种
eval。在javascript中传递的代码。URLs中传递的代码必须被浏览器解析和评估,就像处理eval一样。此外,组装javascript:URLs(或其他包含源代码的字符串)是一项棘手的任务,很容易出现XSS漏洞。例子:
location.href = 'javascript:void(0)' -
防止使用
implied-eval尝试通过使用
setTimeout(),setInterval()或execScript()来消除隐含的eval()。因此,当这两个函数的第一个参数是字符串时,它将发出警告。例子 :
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);
性能
-
在
return,throw,continue, 和break语句之后检测不可达的代码因为
return,throw,break, 和continue语句无条件地退出一个代码块,在它们之后的任何语句都不能被执行。检测并删除它们有助于提高代码的性能。 -
检测未使用的变量
那些在代码中声明了但没有使用的变量,很可能是由于不完整的重构造成的错误。这样的变量会占用代码中的空间并导致混乱。
-
检测空的函数声明和块状语句
空函数会降低可读性,而且最终会占用没有用的空间。空的块状语句,虽然在技术上不是错误,但通常是由于没有完成重构而发生的。它们会在阅读代码时造成混乱,也会影响性能。
例子:
function foo() {} var foo = function () {} var foo = () => {} if (foo) { } while (foo) {}