本文由汤姆·格雷科(Tom Greco),丹·普林斯(Dan Prince)和Yaphi Berhanu进行了同行评审。感谢SitePoint所有的同行评审员制作SitePoint内容的最佳状态! >几乎每个开发人员都有维护或接管旧项目的经验。或者,也许这是一个旧的项目,再次被接管了。常见的第一想法是丢弃代码库,然后从头开始。该代码可能是混乱的,无证的,可能需要几天才能充分理解所有内容。但是,通过适当的计划,分析和良好的工作流程,可以将意大利面条代码库变成干净,有条理且可扩展的一个。
>我不得不接管并清理许多项目。我从头开始没有很多。实际上,我目前正在确切地说。我学到了很多有关JavaScript,保持代码库的组织,最重要的是 - 在以前的开发人员中没有疯狂。在本文中,我想向您展示我的步骤,并告诉您我的经验。
了解更高级别的项目
知道这些技术是一个不错的开始,但是要获得真正的感觉和理解,是时候研究单元测试了。单元测试是测试功能和代码方法的一种方法,以确保代码的行为按预期行为。阅读和运行 - 单位测试比仅阅读代码更深入地了解。如果他们在您的项目中没有单位测试,请放心,我们会来的。
>这就是建立一致性。现在,您已经拥有有关项目工具链的所有信息,您就知道了结构以及逻辑如何连接,现在该创建基线了。我建议添加一个.editorConfig文件,以保持编码样式指南在不同的编辑器,IDE和开发人员之间保持一致。
连贯的凹痕战争 )无关紧要。代码库是用空间写的吗?继续空间。有标签?使用它们。只有当代码库具有混合凹痕时,才有必要决定要使用哪种。意见很好,但是一个好的项目可以确保所有开发人员都可以在没有麻烦的情况下工作。
>为什么这甚至重要?每个人都有自己使用编辑器或IDE的方法。例如,我是代码折叠的忠实拥护者。没有该功能,我实际上会丢失在文件中。当凹痕不连贯时,此功能会失败。因此,每次打开文件时,我都必须在开始工作之前修复缩进。这是一个巨大的时间浪费。
<span>// While this is valid JavaScript, the block can't </span><span>// be properly folded due to its mixed indentation. </span> <span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span> <span>} </span> <span>// Correct indentation makes the code block foldable, </span><span>// enabling a better experience and clean codebase. </span><span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span><span>} </span>
确保尊重项目中使用的命名惯例。骆驼通常在JavaScript代码中使用,但我看到了很多混杂的惯例。例如,jQuery项目通常具有jQuery对象变量和其他变量的混合命名。
><span>// Inconsistent naming makes it harder </span><span>// to scan and understand the code. It can also </span><span>// lead to false expectations. </span><span>const $element = $('.element'); </span> <span>function _privateMethod () { </span> <span>const self = $(this); </span> <span>const _internalElement = $('.internal-element'); </span> <span>let $data = element.data('foo'); </span> <span>//... more logic. </span><span>} </span> <span>// This is much easier and faster to understand. </span><span>const $element = $('.element'); </span> <span>function _privateMethod () { </span> <span>const $this = $(this); </span> <span>const $internalElement = $('.internal-element'); </span> <span>let elementData = $element.data('foo'); </span> <span>//... more logic. </span><span>} </span>
>前面的步骤更加化妆,主要是为了更快地扫描代码,但我们在这里介绍并确保常见的最佳实践以及代码质量。如今,Eslint,JSlint和Jshint是最受欢迎的JavaScript Linters。就我个人而言,我曾经经常与Jshint合作,但是Eslint已开始成为我的最爱,这主要是因为它的自定义规则和ES2015早期支持。
>开始伸长时,如果弹出了很多错误,请修复它们!在您的衬里很高兴之前,不要继续其他任何事情!>
更新依赖项>
>没有更新依赖性的一般规则。每个项目都是不同的,应处理。更新依赖的补丁编号根本不应该是问题,而未成年人通常也可以。只有当您碰到主要依赖项的主要数量时,才能查找到底发生了什么变化。也许API已完全改变,您需要重写应用程序的大部分。如果这不值得付出努力,我将避免更新到下一个主要版本。
>>如果您的项目使用NPM作为依赖项管理器(并且没有任何竞争对手),则可以使用CLI的方便的NPM命令检查任何过时的依赖项。让我用我的一个名为Frontbook的项目中的一个示例来说明这一点,我经常在其中更新所有依赖项:
>
>让我们弄脏建立单位测试
>
单元测试和浏览器自动化之间的差异是,前者对您的JavaScript代码本身进行了测试。它确保您的所有模块和一般逻辑工作。另一方面,浏览器自动化测试项目的表面(用户界面),确保元素在正确的位置并按预期工作。 在开始重构其他任何内容之前,请先注意单位测试。您的项目的稳定性将有所改善,您甚至没有考虑到可伸缩性!一个很大的副作用并不是一直担心您可能会破坏某物并且没有注意到。>
丽贝卡·墨菲(Rebecca Murphey如果您的项目中没有任何架构(也许所有内容都在一个巨大的应用程序中),那么该更改它了。不要一次完成所有操作,而是一件一件。同样,没有通用的方法来做事,每个项目设置都不同。文件夹结构在项目之间有所不同,具体取决于大小和复杂性。通常 - 在非常基本的层面上 - 结构被分为第三方库,模块,数据和入口点(例如index.js,main.js),其中所有模块和逻辑都将初始化。
>
这使我进行了模块化。>模块化所有内容?
>您如何将大量紧密连接的逻辑分开一个大功能?让我们一起做。
这不是很模块化。一切都紧密连接,并取决于其他碎片。想象一下,这具有更大,更复杂的功能,您将不得不对此进行调试,因为某些事情会破裂。也许API没有响应,JSON内部发生了一些变化。一场噩梦,不是吗?
<span>// While this is valid JavaScript, the block can't </span><span>// be properly folded due to its mixed indentation. </span> <span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span> <span>} </span> <span>// Correct indentation makes the code block foldable, </span><span>// enabling a better experience and clean codebase. </span><span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span><span>} </span>
好吧,我们现在有三个新模块。让我们看看重构的获取电话。
>
<span>// Inconsistent naming makes it harder </span><span>// to scan and understand the code. It can also </span><span>// lead to false expectations. </span><span>const $element = $('.element'); </span> <span>function _privateMethod () { </span> <span>const self = $(this); </span> <span>const _internalElement = $('.internal-element'); </span> <span>let $data = element.data('foo'); </span> <span>//... more logic. </span><span>} </span> <span>// This is much easier and faster to understand. </span><span>const $element = $('.element'); </span> <span>function _privateMethod () { </span> <span>const $this = $(this); </span> <span>const $internalElement = $('.internal-element'); </span> <span>let elementData = $element.data('foo'); </span> <span>//... more logic. </span><span>} </span>
记录您的代码
此功能采用两个参数,并在对象上迭代,然后返回一个数组。这可能不是一个过于复杂的方法,但是对于没有编写代码的人来说,可能需要一段时间才能弄清楚发生了什么。此外,该方法的作用并不明显。让我们开始记录:
<span>// While this is valid JavaScript, the block can't </span><span>// be properly folded due to its mixed indentation. </span> <span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span> <span>} </span> <span>// Correct indentation makes the code block foldable, </span><span>// enabling a better experience and clean codebase. </span><span>function foo (data) { </span> <span>let property = String(data); </span> <span>if (property === 'bar') { </span> property <span>= doSomething(property); </span> <span>} </span> <span>//... more logic. </span><span>} </span>
>我没有触摸很多代码本身。仅通过重命名功能并添加了一个简短但详细的评论块,我们就可以提高可读性。
有一个有组织的提交工作流<span>// Inconsistent naming makes it harder </span><span>// to scan and understand the code. It can also </span><span>// lead to false expectations. </span><span>const $element = $('.element'); </span> <span>function _privateMethod () { </span> <span>const self = $(this); </span> <span>const _internalElement = $('.internal-element'); </span> <span>let $data = element.data('foo'); </span> <span>//... more logic. </span><span>} </span> <span>// This is much easier and faster to understand. </span><span>const $element = $('.element'); </span> <span>function _privateMethod () { </span> <span>const $this = $(this); </span> <span>const $internalElement = $('.internal-element'); </span> <span>let elementData = $element.data('foo'); </span> <span>//... more logic. </span><span>} </span>
重构本身就是一个巨大的任务。为了始终能够滚动您的更改(如果您打破某些内容并以后只注意),我建议您进行所有更新。重写方法? git commit(或SVN提交,如果您与SVN合作)。重命名为名称空间,文件夹还是一些图像? git提交。你明白了。对于某些人来说,这可能很乏味,但这确实可以帮助您正确清理并井井有条。
>为整个重构工作创建一个新分支。永远不要在主人上工作!您可能必须进行快速更改或将错误修复程序上传到生产环境中,并且不想部署(可能未经测试的)代码,直到进行测试和完成。因此,建议始终在另一个分支上工作。如何不失去理智
除了清理所需的所有技术步骤外,我很少在任何地方看到一个重要的步骤:对以前的开发人员没有生气。当然,这并不适用于所有人,但我知道有些人会遇到这种情况。我花了数年的时间才真正理解这一点并克服它。我曾经对以前的开发人员代码,他们的解决方案以及为什么一切都如此混乱感到非常生气。
最终,所有的负面情绪永远不会让我带任何地方。它只会导致您重构超出必要的重构,浪费时间,甚至破坏事情。这只是使您越来越烦人。您可能会花费更多的时间,没有人会感谢您重写已经有效的模块。这是不值得的。做需要的事情,分析情况。每次回到模块时,您总是可以重构微小的位。
>始终有理由以其方式编写代码。也许以前的开发人员没有足够的时间来正确地做到这一点,不知道更好或其他。我们都去过那里。
>让我们再次浏览所有步骤,为您的下一个项目创建一个清单。
>有几种可用的工具可以帮助您编写可维护的JavaScript代码。这些包括诸如ESLINT之类的Linter,可以强制执行编码标准并突出代码中的潜在问题。 Visual Studio Code等代码编辑器也可以通过提供语法突出显示和自动完成等功能来提供帮助。此外,诸如GIT之类的版本控制系统可以帮助您跟踪代码的更改,并使与他人合作更容易。
>评论在维护JavaScript代码中的重要重要性是多么重要?
>我如何确保我的javascript代码可扩展?您的JavaScript代码可扩展,涉及以一种允许其有效处理增加负载的方式设计您的代码。这可以通过遵循良好的编程实践,例如使用有效的算法和数据结构,避免全局变量并最大程度地减少DOM操纵。此外,使用模块化方法的编码方法,其中您的代码被分解为较小的可重复使用的零件,也可以增强可扩展性。
>以上是解开意大利面条代码:编写可维护的JavaScript的详细内容。更多信息请关注PHP中文网其他相关文章!