当前位置: 首页 > 科技观察

JavaScript静态代码分析新手指南_0

时间:2023-03-12 13:24:31 科技观察

【.com快考】你有过写代码的困惑吗?您的代码库是否存在不一致?每次review你的代码时你是否感到焦虑??如果您对这些问题中的任何一个的回答是肯定的,那么静态代码分析应该能够帮助您。所谓静态代码分析,是指在执行代码之前对代码进行分析的过程。通过集成静态代码分析器,开发人员可以优化整个工作流程。本文将向您介绍什么是JavaScript静态代码分析,为什么要使用它,以及如何在您的项目中通过快速设置来实现它。什么是静态代码分析?顾名思义,静态代码分析就是分析处于静态或非执行状态的代码。这实际上等同于让另一位开发人员阅读和审查您的代码。当然,它可能不如自动化工具高效。它与测试有何不同?无论是单元测试、功能测试、集成测试、可视化测试还是回归测试,所有这些类型的测试都是通过运行代码,将结果与已知的预期输出状态进行比较,检查是否一切正常。可以说,测试就是把你的代码当作一个黑盒子,通过向它提供输入并在执行后验证输出来确保代码的行为符合预期。而静态代码分析主要是针对程序代码的可读性、一致性、错误处理、类型检查、缩进等进行分析。可以说,静态分析关心的不是代码是否提供了预期的输出,而是代码本身的编写方式。它是对源代码质量(而非功能)的分析。总而言之,测试着眼于检查代码是否有效,而静态分析则检查代码是否正确编写。理想情况下,您应该让测试和静态分析在您的项目中相互补充。为什么要使用静态代码分析?从程序格式化小工具,到漏洞扫描器,甚至程序审查器,任何可以读取源代码、解析源代码并提出改进建议的工具都是静态代码分析器。接下来我们看看有哪些工作场景使用了静态代码分析。全面的审稿人是容易犯错的。据统计,JSHint(一种流行的JavaScript代码审查工具)代码库的安装过程只有15%可以顺利通过。俗话说“当局者迷,旁观者清”,“第二双眼睛”往往能发现自己代码中你永远不会注意到的问题。开发者据此不仅可以了解项目内置的一些功能,还可以提出更好更方便的实现方式。那么,能否引入更多的“眼睛”、更全面的“扫描”呢?通常,静态分析器得到大型开源社区的支持。这意味着为该工具做出贡献的每个人都间接检查了您的代码是否存在任何遗漏的错误。示例:以下代码片段显示了让用户挑选水果的示例。如果用户不做选择,它默认为“Mango”。letfruits=['Apple','Banana','Cherry','Mango']functiongetFruit(index){index=index||3//Everybodylikesmangoesreturnfruits[index]}只要用户输入不为0,那么各种测试都可以通过。getFruit()//MangogetFruit(2)//CherrygetFruit(0)//Mango(expectedApple!)由于0的存在,用户无法选择Apple。所以对于像null和undefined这样的falsy值,你应该使用null-coalescingoperator--??(请参阅以下代码片段)。letfruits=['Apple','Banana','Cherry','Mango']functiongetFruit(index){index=index??3//Everybodylikesmangoesreturnfruits[index]}统一风格每个开发者都可以用自己的风格去写代码.然而,当许多开发人员需要一起工作时,通过风格指南的一致性来约束每个人的编程是极其重要的。但是,要开发者死记硬背指南中的数百条规则,靠人工逐行对比检查是不可能的。所以我们需要依靠自动化来做。每种语言都有自己的代码验证器(lint),例如:JavaScript有ESLint(https://eslint.org/),Python有Black(https://black.readthedocs.io/en/stable/),Ruby有RuboCop(https://github.com/rubocop-hq/rubocop)。这些验证器可以确保您的代码遵循相关的样式规则,从而使您的代码更简洁。例如,RuboCop通过检测和修复错误来确保函数和变量名称更好的原子一致性。示例:以下JavaScript片段旨在打印列表中的水果名称。同时,该列表应在整个程序中保持不变。varfruits=['Apple','Banana','Cherry','Mango']console.log(fruits[0])通过配置,ESLint可以保证尽可能使用常量,避免对代码产生副作用。constfruits=['Apple','Banana','Cherry','Mango']console.log(fruits[0])如上代码所示,如??果我们将var替换为let和const关键字,会让代码更简单调试。立即发现问题测试驱动开发实践通常强调编写各种用例进行测试。然而,为了尽可能覆盖所有输入,开发人员需要花费时间和精力编写测试用例。最后,测试用例不仅臃肿,而且需要数小时才能完成大型代码库的构建。静态代码分析器不会遇到这样的问题。您不需要编写测试用例,您可以导入整个预设代码库。同时,由于不需要执行代码,静态分析器将运行得更快。事实上,许多代码验证器与代码编辑器集成在一起,并在您键入代码时实时突出显示代码中的问题。示例:大多数静态分析器,尤其是linter和格式化程序,不仅会指出代码问题,还会修复它们。同时,如Python的Black和JavaScript的ESLint也可以与IDE集成。它们可以在用户保存代码时自动修复当前编辑的文件。这种实时提升代码质量的方法受到了开发者的广泛欢迎。示例:ESLint自带一个参数--fix可以用来修复常见问题,可以用来修复:不必要的分号、尾随空格和多余的逗号。在下面的代码段中,一个·代表一个空格。varfruits=['苹果','香蕉','樱桃',··'芒果'];加上--fix运行ESLint后,代码会变成:constfruits=['Apple','Banana','Cherry','Mango',]Fixingdependencies在构建应用程序时,你不可避免地会使用其他人构建的框架和工具开发商。当然,其他开发者也可能使用更多的第三方框架。如果这种情况继续下去,即使是一个简单的Vue.js应用程序也可能在其node_modules/目录中放置数千个包。但是,在这个“堆叠”的依赖链中,您的应用程序受到最弱依赖的约束。漏洞扫描器,另一种静态分析器,可以利用强大的漏洞签名数据库来检查依赖树中的每个依赖项。并且扫描程序可以通过单个命令更新和修复所有发现的漏洞。示例:GitHub使用Dependabot扫描依赖项。npm将使用npmaudit命令扫描漏洞。Dependabot和npmaudit都在其新版本中提供了带有自动错误修复的更新包。自动化重复性任务相比繁琐的手动遍历和审查代码,各种linters、formatter和spellcheckers(拼写检查器)可以大大简化整个过程。那么他们是怎么做到的呢?首先,预提交挂钩将确保代码在被签入VCS(版本控制系统)之前经过检查和格式化。其次,项目级自动化以构建管道或GitHub工作流的形式出现,在每次提交时检查代码质量并突出显示代码本身的问题。最后,由于代码的各种小问题已经处理完毕,审阅者可以专注于代码逻辑等其他问题。由此可见,软件自动化不仅可以减少人工的工作量,还可以提高审核速度和遍历覆盖率。示例项目接下来,让我们来看看示例项目的创建。首先,我们为项目创建一个新目录。在这个目录下,我们通过npminit向导逐步完成Node.js包的初始化(如下图所示)。$mkdirwuphf.com$cdwuphf.com$npminit我们使用以下简单命令来安装ESLint。$npminstalleslint我们运行以下命令来激活ESLint向导。$./node_modules/.bin/eslint--init这个向导会和你交互,完成项目中如何使用ESLint的相关问题。对于此示例,选择Airbnb规则集。设置完成后,该目录下会出现一个.eslintrc.js文件。下面的代码片段显示了一个控制台应用程序。在这里,我们可以自定义规则并为其关闭各种警告。module.exports={env:{es2021:true,node:true,},extends:['airbnb-base',],parserOptions:{ecmaVersion:12,},overrides:[{files:['*.js'],rules:{'no-console':'off',},},],};最后,我们将这个文件提交到版本控制系统,以便ESLint不断扫描项目中的所有JS文件。另外,我建议大家在每次提交前安装Husky(https://typicode.github.io/husky/#/)运行一次代码验证作业,确保不会有坏代码被CheckinVCS。使用DeepSource实现自动化作为静态代码分析器,DeepSource(https://deepsource.io/)可以发现代码库中的问题并自动修复它们。目前支持大部分主流编程语言,可以集成到GitHub、GitLab和Bitbucket中。为了在您的项目中设置DeepSource,您将一个名为.deepsource.toml的文件放在存储库的根目录中,以便持续扫描您的项目。原标题:JavaScript静态代码分析新手指南,作者:DhruvBhanushali