首页 > web前端 > js教程 > 解开意大利面条代码:编写可维护的JavaScript

解开意大利面条代码:编写可维护的JavaScript

William Shakespeare
发布: 2025-02-18 11:49:09
原创
257 人浏览过

解开意大利面条代码:编写可维护的JavaScript

本文由汤姆·格雷科(Tom Greco),丹·普林斯(Dan Prince)和Yaphi Berhanu进行了同行评审。感谢SitePoint所有的同行评审员制作SitePoint内容的最佳状态! >几乎每个开发人员都有维护或接管旧项目的经验。或者,也许这是一个旧的项目,再次被接管了。常见的第一想法是丢弃代码库,然后从头开始。该代码可能是混乱的,无证的,可能需要几天才能充分理解所有内容。但是,通过适当的计划,分析和良好的工作流程,可以将意大利面条代码库变成干净,有条理且可扩展的一个。

>我不得不接管并清理许多项目。我从头开始没有很多。实际上,我目前正在确切地说。我学到了很多有关JavaScript,保持代码库的组织,最重要的是 - 在以前的开发人员中没有疯狂

。在本文中,我想向您展示我的步骤,并告诉您我的经验。

钥匙要点

  • 首先了解项目:在进行编码之前,彻底分析现有代码库,了解所使用的技术和工具,并研究任何可用的文档或单位测试,以更深入地了解该项目的功能。
  • >
  • 建立一个一致的编码标准:实现“ .editorConfig”文件,以维持不同开发人员使用的各种编辑器和IDE的一致编码样式。这包括一致的凹痕和遵守命名惯例。
  • >实施刺伤工具:使用诸如ESLINT之类的JavaScript Linter来执行编码标准和最佳实践,确保代码质量并帮助在开发过程的早期识别和修复错误。
  • 明智地管理依赖性:谨慎地更新项目依赖性,了解主要,次要和补丁版本的变化的含义,以避免将新错误引入项目。
  • 重新谨慎的重构:专注于在适当的情况下模块化代码库,将复杂功能分解为遵循单个责任原则的较小,可管理和可重复使用的模块。
  • >文档并定期提交:使用JSDOC进行全面的文档,并通过定期承诺进行有组织的提交工作流程,以跟踪更改并在必要时促进回滚。始终在与大师的单独分支上工作,以有效地管理重构和新功能。
  • >
  • 分析项目
>第一步是概述正在发生的事情。如果是一个网站,请单击所有功能:打开模式,发送表格等。在这样做的过程中,让开发人员工具打开,以查看是否弹出任何错误或已记录任何错误。如果是node.js项目,请打开命令行接口并通过API。在最好的情况下,该项目具有一个入口点(例如main.js,index.js,app.js,…),其中所有模块均已初始化,或者在最坏的情况下,整个业务逻辑已找到。

找出正在使用的工具。 jQuery?反应?表达?列出所有重要的知识。假设该项目是用Angular 2编写的,您尚未与之合作,直接介绍文档并获得基本的理解。搜索最佳实践。

了解更高级别的项目

知道这些技术是一个不错的开始,但是要获得真正的感觉和理解,是时候研究单元测试了。单元测试是测试功能和代码方法的一种方法,以确保代码的行为按预期行为。阅读和运行 - 单位测试比仅阅读代码更深入地了解。如果他们在您的项目中没有单位测试,请放心,我们会来的。

>

创建一个基线

这就是建立一致性。现在,您已经拥有有关项目工具链的所有信息,您就知道了结构以及逻辑如何连接,现在该创建基线了。我建议添加一个.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早期支持。

>开始伸长时,如果弹出了很多错误,请修复它们!在您的衬里很高兴之前,不要继续其他任何事情!

>

更新依赖项

>更新依赖项应仔细完成。当不关注依赖性经历的变化时,很容易引入更多错误。一些项目可能与固定版本(例如V1.12.5)一起使用,而另一些项目则使用通配符版本(例如V1.12.x)。如果您需要快速更新,则构建版本号如下:major.minor.patch。如果您不熟悉语义版本的工作方式,我建议您阅读Tim Oxley的这篇文章。

>

>没有更新依赖性的一般规则。每个项目都是不同的,应处理。更新依赖的补丁编号根本不应该是问题,而未成年人通常也可以。只有当您碰到主要依赖项的主要数量时,才能查找到底发生了什么变化。也许API已完全改变,您需要重写应用程序的大部分。如果这不值得付出努力,我将避免更新到下一个主要版本。

>

>如果您的项目使用NPM作为依赖项管理器(并且没有任何竞争对手),则可以使用CLI的方便的NPM命令检查任何过时的依赖项。让我用我的一个名为Frontbook的项目中的一个示例来说明这一点,我经常在其中更新所有依赖项:>

解开意大利面条代码:编写可维护的JavaScript

>您可以看到,我在这里有很多重大更新。我不会一次更新所有这些,而是​​一次更新。当然,这将需要大量时间,但这是确保任何事情都没有破坏的唯一方法(如果项目没有任何测试)。

>

>让我们弄脏

>我希望您随身携带的主要消息是,清理并不一定意味着删除和重写大型代码。当然,这有时是唯一的解决方案,但它不应该是您的第一步也是唯一的一步。 JavaScript可能是一种奇怪的语言,因此通常不可能提供通用建议。您始终必须评估您的特定情况并找出工作解决方案。

建立单位测试

进行单元测试可确保您了解代码的工作原理,并且您不会意外地破坏任何内容。 JavaScript单元测试值得自己的文章,因此我将无法在此处详细介绍。广泛使用的框架是业力,茉莉,摩卡或Ava。如果您还想测试用户界面,建议使用Nightwatch.js和Dalekjs浏览器自动化工具。

>

单元测试和浏览器自动化之间的差异是,前者对您的JavaScript代码本身进行了测试。它确保您的所有模块和一般逻辑工作。另一方面,浏览器自动化测试项目的表面(用户界面),确保元素在正确的位置并按预期工作。 在开始重构其他任何内容之前,请先注意单位测试。您的项目的稳定性将有所改善,您甚至没有考虑到可伸缩性!一个很大的副作用并不是一直担心您可能会破坏某物并且没有注意到。

>

丽贝卡·墨菲(Rebecca Murphey

架构

JavaScript体系结构是另一个重要主题。重构和清理建筑归结为您对此的经验。我们在软件开发中有许多不同的设计模式,但并非所有这些模式在可伸缩性的地方都很好。不幸的是,我将无法介绍本文中的所有案例,但至少可以给您一些一般建议。 首先,您应该找出项目中已经使用了哪些设计模式。阅读有关模式的信息,并确保其一致。可伸缩性的关键之一是粘在模式上,而不是混合方法。当然,您可以在项目中具有不同的设计模式(例如,使用Singleton模式用于数据结构或短名称助手功能,以及模块的观察者模式),但切勿用一个模式编写一个模块,而另一种模块则不应编写一个模块一个具有不同模式的。

如果您的项目中没有任何架构(也许所有内容都在一个巨大的应用程序中),那么该更改它了。不要一次完成所有操作,而是一件一件。同样,没有通用的方法来做事,每个项目设置都不同。文件夹结构在项目之间有所不同,具体取决于大小和复杂性。通常 - 在非常基本的层面上 - 结构被分为第三方库,模块,数据和入口点(例如index.js,main.js),其中所有模块和逻辑都将初始化。

>

这使我进行了模块化。

>模块化所有内容?

到目前为止,模块化不是对伟大的JavaScript可伸缩性问题的答案。它增加了开发人员必须熟悉的另一层API。不过,这可能值得麻烦。该原理正在将您的所有功能分解为微小的模块。通过这样做,可以更容易解决代码中的问题并在同一代码库中的团队中工作。每个模块都应该完全有一个目的和任务。一个模块不知道您的应用程序的外部逻辑,并且可以在不同的位置和情况下重复使用。

>

>您如何将大量紧密连接的逻辑分开一个大功能?让我们一起做。

这不是很模块化。一切都紧密连接,并取决于其他碎片。想象一下,这具有更大,更复杂的功能,您将不得不对此进行调试,因为某些事情会破裂。也许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>
登录后复制
登录后复制
登录后复制
>我们也可以从.then()方法内部获取逻辑并将其分开,但是我认为我已经证明了模块化的含义。

如果!模块化还有什么?

> 正如我已经提到的那样,在微小模块中转动您的代码库会添加另一层API。如果您不想要它,但希望使其他开发人员更容易使用代码,那么保持功能更大是绝对可以的。您仍然可以将代码分解为更简单的部分,并更多地关注可测试的代码。>

记录您的代码

文档是一个经过广泛讨论的主题。编程社区倡导记录所有内容的一部分,而另一个小组认为自我记录的代码是必经之路。与生活中的大多数事情一样,我认为两者都可以保持代码可读和可扩展。将JSDOC用于您的文档。

JSDOC是JavaScript的API文档生成器。通常可以作为所有知名编辑和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>
登录后复制
登录后复制
登录后复制

>我没有触摸很多代码本身。仅通过重命名功能并添加了一个简短但详细的评论块,我们就可以提高可读性。

有一个有组织的提交工作流
<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提交。你明白了。对于某些人来说,这可能很乏味,但这确实可以帮助您正确清理并井井有条。

>为整个重构工作创建一个新分支。永远不要在主人上工作!您可能必须进行快速更改或将错误修复程序上传到生产环境中,并且不想部署(可能未经测试的)代码,直到进行测试和完成。因此,建议始终在另一个分支上工作。

>

>如果您需要简短的更新所有这些工作的工作方式,则GitHub的一个有趣的指南在其版本控制工作流程中。

如何不失去理智

除了清理所需的所有技术步骤外,我很少在任何地方看到一个重要的步骤:对以前的开发人员没有生气。当然,这并不适用于所有人,但我知道有些人会遇到这种情况。我花了数年的时间才真正理解这一点并克服它。我曾经对以前的开发人员代码,他们的解决方案以及为什么一切都如此混乱感到非常生气。

最终,所有的负面情绪永远不会让我带任何地方。它只会导致您重构超出必要的重构,浪费时间,甚至破坏事情。这只是使您越来越烦人。您可能会花费更多的时间,没有人会感谢您重写已经有效的模块。这是不值得的。做需要的事情,分析情况。每次回到模块时,您总是可以重构微小的位。

>

始终有理由以其方式编写代码。也许以前的开发人员没有足够的时间来正确地做到这一点,不知道更好或其他。我们都去过那里。

>将其包裹起来

>让我们再次浏览所有步骤,为您的下一个项目创建一个清单。>

    分析项目
    >将开发人员的帽子放在片刻中,并成为用户查看它的全部内容。
  • 浏览代码库,并列出使用中的工具。>
  • 读取工具的文档和最佳实践。
  • 进行单元测试,以在更高级别上了解该项目。
  • 创建一个基线
  1. 介绍.editorConfig以保持编码样式指南在不同的IDE之间保持一致。
    使凹痕保持一致;标签或空格,没关系。
  • 强制执行命名约定。
  • 如果尚未存在,请添加诸如Eslint,JSlint或Jshint之类的Linter。
  • 更新依赖性,但要明智地做并注意确切的更新。
  • 清理
    >使用业力,茉莉花或nightwatch.js。
  1. 确保体系结构和设计模式是一致的。
  2. >
不要混合设计图案,坚持已经存在的图案。
    >决定是否要将代码库分为模块。每个人都只能有一个目的,并且不知道您的代码库逻辑的其余部分。>
  • 如果您不想这样做,请更多地关注可测试的代码,然后将其分解为更简单的块。
  • >以平衡的方式记录您的功能和代码。
  • >使用JSDOC为您的JavaScript生成文档。
  • 定期进行,并在重要的更改之后进行。如果有什么破裂,那么回去就更容易。
  • >
  • 不要失去理智
  • 不要对以前的开发人员生气;消极情绪只会导致不必要的重构和浪费时间。
  • >
  • >有理由编写代码的原因。请记住,我们都去过那里。
    >我真的希望这篇文章对您有所帮助。让我知道您是否在任何步骤中挣扎,或者也许有一些我没有提及的好建议!
  1. >

    经常询问的问题(常见问题解答)关于编写可维护的JavaScript

    什么是意大利面代码,为什么要避免它?

    意大利面代码是一个用来描述一个复杂而纠结的代码网络的术语,难以阅读,理解和维护。它通常是由于缺乏计划,不遵循编码标准或不使用面向对象的编程原则等编程实践而引起的。这种类型的代码可能会导致许多问题,包括难以追踪的错误,添加新功能的困难以及增加的时间和成本。因此,至关重要的是要避免编写意大利面条代码,而要努力寻求清洁,可维护的代码。

    我如何编写可维护的JavaScript代码? >编写可维护的JavaScript代码涉及几种最佳实践。首先,在开始写作之前,请务必计划您的代码。这包括了解您要解决和设计解决方案的问题。其次,遵循编码标准和约定。这使您的代码易于阅读和理解。第三,使用面向对象的编程原理。这有助于组织您的代码,并使其更加重复使用。最后,始终记录您的代码。这包括编写评论以解释您的代码的作用以及为什么您做出某些决定。包括不使用严格的模式,不要正确声明变量,使用“ ==”操作员而不是'===',而不是正确处理错误。避免这些陷阱可以帮助您编写更清洁,更可维护的代码。

    >如何将现有的意大利面条代码重构为可维护的代码?

    >重构意大利面条代码到可维护的代码中涉及几个步骤。首先,您需要了解现有代码。这可能涉及阅读代码并记录每个部分的作用。其次,确定可以改进的代码区域。这可能是重复,复杂的条件逻辑或难以理解的代码的部分。第三,对代码进行必要的更改。这可能涉及将复杂的功能分解为较小,更易于管理的功能,删除重复的代码或重写代码的部分,以使其易于理解。最后,测试您的更改,以确保代码的功能保持不变。

    我可以使用哪些工具来帮助编写可维护的JavaScript代码?

    >有几种可用的工具可以帮助您编写可维护的JavaScript代码。这些包括诸如ESLINT之类的Linter,可以强制执行编码标准并突出代码中的潜在问题。 Visual Studio Code等代码编辑器也可以通过提供语法突出显示和自动完成等功能来提供帮助。此外,诸如GIT之类的版本控制系统可以帮助您跟踪代码的更改,并使与他人合作更容易。

    面向对象的编程如何编写可维护的代码?面向对象的编程(OOP)是一个编程范式,有助于编写可维护的代码。它允许您将代码组织到对象中,该对象可以包含数据和功能。这使您的代码更加模块化和重复使用,因为您可以创建执行特定任务的对象,然后在整个代码中使用它们。 OOP还可以使您的代码更易于理解,因为它允许您在代码中建模现实世界概念。

    >评论在维护JavaScript代码中的重要重要性是多么重要?

    >评论对于维护JavaScript至关重要代码。它可以帮助其他开发人员(以及您的未来自我)了解代码的作用以及为什么做出某些决定。这在复杂的代码库中尤其重要,在复杂的代码库中,了解代码的功能可能具有挑战性。但是,应明智地使用评论。过度注释会使代码变得混乱且难以阅读。理想情况下,您的代码应该是不言自明的,并保留评论以说明为什么做出某些决定或澄清代码的复杂部分。

    >

    >我如何确保我的javascript代码可扩展?您的JavaScript代码可扩展,涉及以一种允许其有效处理增加负载的方式设计您的代码。这可以通过遵循良好的编程实践,例如使用有效的算法和数据结构,避免全局变量并最大程度地减少DOM操纵。此外,使用模块化方法的编码方法,其中您的代码被分解为较小的可重复使用的零件,也可以增强可扩展性。

    >

    >测试在编写可维护的JavaScript代码中的作用是什么?测试在编写可维护的JavaScript代码中起着至关重要的作用。它有助于确保您的代码能够按预期工作,并可以在开发过程的早期捕获错误。您可以使用几种类型的测试,包括单元测试,集成测试和端到端测试。使用这些测试方法的组合可以帮助确保您的代码坚固且可靠。

    >

    >如何跟上编写可维护的JavaScript代码的最新最佳实践? ,参与在线社区。此外,练习持续学习并定期审查和重构您的代码也可以帮助您保持最新的最新最佳实践。

    >

以上是解开意大利面条代码:编写可维护的JavaScript的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板