选择 JavaScript 库或框架

Umar Hansa
Umar Hansa

本文介绍了如何选择要在 Web 应用中使用的库或框架。本文中的讨论将有助于您权衡找到适合您试图解决的业务问题的 JavaScript 库或框架的利弊。了解不同情况下的优缺点是审查大量可用的 JavaScript 库选择的关键。

什么是 JavaScript 库和框架

什么是 JavaScript 库?最简单的方式是,JavaScript 库是预先编写的代码,您可以在项目代码中调用此代码以实现特定任务。

这篇博文主要提到了“库”。但是,许多讨论也适用于框架。基本上,两者之间的区别可总结如下:

  • 对于库,您的应用代码会调用库代码。
  • 对于框架,您的应用代码由框架调用。

以下实际示例有助于说明不同之处。

调用 JavaScript 库的示例

JavaScript 库会执行一项特定任务,然后将控制权交还给您的应用。使用库时,您可以控制应用流程并选择何时调用库。

在下面的示例中,应用代码从 lodash 库导入一个方法。函数运行完毕后,控制权将交还给您的应用。

import capitalize from 'lodash.capitalize';
capitalize('hello'); // Hello

执行 lodash.capitalize 方法时,它会调用预先编写的 JavaScript 代码,这些代码会将字符串的第一个字符大写。

JavaScript 框架的使用示例

JavaScript 框架是一种预定义的代码模板,您可以在该模板中构造应用的行为。也就是说,当您使用框架时,框架会控制应用流程。要使用框架,请编写自定义应用代码,然后框架调用您的应用代码。

以下示例展示了使用 Preact JavaScript 框架的代码段:

import { createElement } from 'preact';

export default function App() {
  return (
    <p class="big">Hello World!</p>
  )
}

在本例中,请注意,框架对您编写的代码拥有更多控制权,并且在某些情况下,框架甚至还可以控制何时执行代码。

为什么要使用库?

使用 JavaScript 库有助于避免不必要的代码重复。库可以抽象化复杂的逻辑,例如日期操作或财务计算。库还可以帮助您发布初始产品,而无需从头开始编写所有代码,因为这需要花费一些时间。

有些客户端 JavaScript 库有助于消除网络平台中的怪异元素。库也可以用作学习工具。例如,如果您不熟悉动画加/减速函数,可以查看库的源代码,了解此类加/减速选项的运作方式。

有些库得到大公司的支持,他们投入时间和金钱来及时更新库并确保其安全。许多库都附带大量文档,您和您的团队可以快速熟悉库的使用方式。

归根结底,使用 JavaScript 库可以节省时间。

为何应关注库的使用情况?

从技术层面来讲,您可以从头开始开发自己的 Web 应用,但是,既然您可以使用免费的(开源)软件,或购买从长远来看可以节省时间和金钱的解决方案,那又何必再费力气呢?目前,有大量的 JavaScript 库和框架可供使用,每种库和框架都有自己独特的问题解决方法,而且各有不同。例如:

  • 库可由内部(而非第三方)编写和维护。
  • 库可能具有特定的法律许可,这决定了其是否适合您的 Web 应用。
  • 库可能已过时或未维护。
  • 库可以简化一组复杂任务,并为您节省大量时间和金钱。
  • 库可以在社区中广泛使用,在开发者中广为人知。

您可能怀疑,不同的特性会以不同的方式影响您的 Web 应用。有时,决定并没有那么深刻,如果您不喜欢某个库,可以放心地更换库。不过,有时库可能会对您的工作和 Web 应用产生重大影响,这表明有必要采用更明智的方法。

还有一些非客户端 JavaScript 环境,例如在服务器(在云环境中运行)或 Raspberry Pi 上,在这些环境中,您可能需要调整用于审查库和框架的标准。

性能

不应忽略 JavaScript 库对客户端 Web 应用的性能影响。大型 JavaScript 库可能会影响网页的加载性能;请注意,毫秒提升数百万

请设想一个使用 JavaScript 库实现动画的场景。有些库很容易增加几十 KB,在某些情况下甚至增加数百 KB。此类 JavaScript 资源可能会显著增加网页加载延迟,因为浏览器需要下载、解析、编译和执行代码。

JavaScript 库越大,对用户的性能影响就越大。

在评估或使用 JavaScript 库或框架时,请考虑以下有助于提升性能的建议:

  • 如果 JavaScript 库较大,请考虑使用较小的替代库。例如,date-fns 以比一些其他选项更合理的大小提供很多功能。
  • 在前面的 date-fns 示例的基础上,仅导入所需的函数,例如:import { format } from 'date-fns'。请务必将此方法与摇树优化结合使用,以尽可能减少构建 JavaScript 载荷并将其发送给用户。
  • 使用 Lighthouse 等性能测试工具可观察使用特定 JavaScript 库的性能影响。如果库会增加 1 秒的网页加载延迟(不要忘记在测试期间对网络和 CPU 进行限制),那么您可能需要重新评估所选择的库。除了检查网页加载之外,请务必分析从相关库中调用代码的所有网页行为,网页加载性能并不能说明所有情况。
  • 如果库作者欢迎评论,请提交您的表现观察结果、建议,甚至是您对项目的贡献。这是开源社区的亮点所在!如果您决定贡献自己的资金,可能需要先与您的雇主确认。
  • 使用自动的软件包跟踪工具(如 bundlesize)可监视库是否有意外大的更新。JavaScript 库随时间增加的情况很常见。功能添加、问题修复、极端情况等都会增加库的文件大小。在您/您的团队同意使用库后,更新库可能就不那么那么麻烦了,而且可能引发一些小问题甚至没有问题。这时,自动化操作就派上用场了。
  • 查看您对库的要求,并评估 Web 平台能否以原生方式提供相同的功能。例如,网络平台已提供颜色选择器,这样无需使用第三方 JavaScript 库即可实现相同的功能。

安全性

使用第三方模块会带来一些固有的安全风险。Web 应用代码库中的恶意软件包可能会危害开发团队和用户的安全。

考虑将一个库发布到 NPM 生态系统。此类文件包可能是合法的。但是,随着时间的推移,软件包可能会遭到入侵。

以下是在使用或评估第三方代码时需要考虑的一些安全提示:

  • 如果您使用 GitHub,请考虑代码的安全产品,例如 Dependabot。或者考虑使用其他可扫描代码中漏洞的服务,例如 snyk.io
  • 不妨考虑使用代码审核服务,也就是由可手动审核您使用的第三方代码的工程师团队。
  • 您可以评估是应该将依赖项锁定为特定版本,还是应该在版本控制内提交第三方代码。这有助于将您的依赖项锁定到一个可以认为安全的特定版本。具有讽刺意味的是,这可能会在安全性方面产生负面影响,因为您可能会错过库的重要更新。
  • 扫描项目首页或 GitHub 页面(如果存在)。调查是否存在未解决的安全问题,以及之前的安全问题是否已在合理的时间范围内解决。
  • 零依赖项的库相比,使用其他第三方代码的第三方代码可能带来更大的风险。请留意这种风险。

无障碍功能

您可能想知道软件库与网络无障碍功能的关系。虽然软件库可以在不同环境中使用,但对于基于 JavaScript 的客户端库,网页无障碍功能至关重要。

基于 JavaScript 的客户端库(或相关的框架)可能会增加或减少网站的可访问性。假设有一个向网页添加图像滑块的第三方 JavaScript 库。如果图片滑块没有将网页无障碍功能考虑在内,那么您作为 Web 开发者,可能会忽略此类重要功能,并发布缺少关键功能的产品,例如滑块可通过键盘进行导航!

  • 自适应排版插件是否支持放大或缩小页面的用户?
  • 文件上传器插件是否支持通过辅助设备上传文件?
  • 动画库是否为喜欢减少动态效果的用户提供支持?
  • 互动式地图插件是否支持纯键盘操作?
  • 音频播放器库在屏幕阅读器上是否提供合适的体验?

理所应当,您(Web 开发者)需要一定程度的参与才能满足此类无障碍功能要求。例如:

  • 对于任何缺失的功能,您可以在代码库中实现这些功能,即使继续使用相关库也是如此。
  • 在您雇主的支持下,您可以为库贡献此类缺失的功能(前提是库作者允许提供此类贡献)。
  • 您可以打开与库作者的对话。例如,这些特定的无障碍功能是否在路线图中?你同意它们属于图书馆吗?
  • 对于热门用例,您可以探索更易于访问的替代库选项;它们可能存在但难以找到。
  • 在极端情况下,您可能需要完全弃用库,从头开始实现相关功能。如果某个库或框架在初次使用时无障碍功能体验下降,因此您需要免费撤消该库或框架本应为您提供的大量内容,这时就可能发生这种情况。

惯例

遵循既定编码规范的软件库更易于使用。如果库使用闻所未闻的编码规范,您和您的团队可能很难使用此类库。

如果库未遵循常用的编码规范(例如,通用样式指南),则没有什么方法可以立即解决问题。不过,您有几个选择:

  • 请务必区分库源代码和向您(库用户)公开的 API。虽然内部源代码可能使用了不熟悉的约定,但如果 API(您与之交互的库部分)使用了熟悉的约定,那么您完全不必担心。
  • 如果库 API 不遵循常见的编码规范,您可以使用 JavaScript 设计模式(如代理模式),将与该库的所有交互封装并包含到代码库中的单个文件中。这样,您的代理就可以为代码库中代码的其他部分提供更直观的 API。

惯例因易于使用而发挥着重要作用。与需要大量实验才能找出的反直觉 API 相比,包含直观 API 的库可以节省数小时甚至数天的时间。

更新

例如,对于需要执行一些数学计算且完全正常运行的库,此类库可能很少需要更新。事实上,在不断变化的 Web 开发世界中,功能齐全的库是不常见的!但有时,您希望库作者及时回应并愿意进行更新。新的研究和发现可以揭示更好的做事方式,因此库和框架中使用的技术总是会发生变化。

选择库或框架时,请注意更新的处理方式,并注意此类决定可能会影响您:

  • 库是否有合理的发布时间表?例如,对源代码库的更新可能会频繁发生,但如果没有相应地“发布”或“发布”此类更新,您会发现下载此类更新并非易事。
  • 库是否使用合理的软件版本控制方案发布更新?库可以帮您节省时间。如果您每次更新库版本时都必须意外更改代码,那么从一开始就可能无法使用该库。有时不可避免地会做出破坏性更改,但在理想情况下,更改并不频繁,也不强制对库使用者执行更改。
  • 该库是否会在实现向后兼容性方面投入精力?有时,软件更新可能会带来破坏性更改,但也能提供一层向后兼容性。这样一来,库使用方就能使用最新的库版本,而且只需对代码进行极少的更改。

许可

软件许可是使用第三方软件库的一个重要方面。图书馆作者可以向其图书馆分配许可。如果您正在考虑使用该库,那么他们的许可选择可能会影响您。

例如,某个 JavaScript 库可能具有允许您在非商业环境中使用它的软件许可。如果是个人的爱好项目,这可能是一个不错的选择。如果您的项目包含商业元素,您可能需要考虑购买企业版许可。

如有疑问,请考虑寻求专业的法律建议或咨询公司内部的法律团队。

社区

拥有庞大的用户/贡献者社区的库或框架可能会非常有用,但并不保证一定是这样。一般来说,库或框架的用户越多,受益的可能性越大。考虑加入开发社区的以下优缺点:

优点:

  • 如果用户群规模庞大,可能就更容易被及早发现、经常发现错误。
  • 建立一个大型的活跃社区意味着提供更多关于相关库或框架的教程、指南、视频,甚至课程。
  • 活跃的大型社区可能意味着在论坛和问答网站上获得更多支持,从而提高支持问题得到解答的可能性。
  • 积极参与的社区可能意味着库或框架有更多外部贡献者。他们可以帮助提交未包含在开发者路线图中的功能。
  • 当某个库或框架在社区中很受欢迎时,您的同行和同事听说甚至熟悉这种库或框架的可能性会提高。

缺点:

  • 用户群规模庞大且多样化的项目可能会因不断增加功能而变得臃肿。膨胀的库可能会影响 Web 性能。
  • 项目拥有活跃且参与度高的社区会给作者和维护人员带来压力,并可能需要大量的社区管理。
  • 发展迅速但得不到适当支持的项目可能会开始表现出存在恶意社区的迹象。例如,如果设有限制,初级或初级的 Web 开发者都可能会因为某个社区设有限制而感到不受欢迎。

文档

无论 JavaScript 库或框架有多简单或多么复杂,软件文档都可以随时为您提供帮助。即使是非常有经验的开发者也要使用文档,而不是自己弄清楚代码。该文档阐明了您应使用的 API 和使用方式。

文档甚至可以提供示例代码,帮助您更轻松地快速上手。在评估库或框架时,您可以提出以下一些问题:

  • 该库是否包含文档?如果不是这样,您就应该能够游刃有余地自行寻找解决方法。
  • 文档是否清晰易懂,没有歧义?许多开发者在编写文档时会花费大量时间。这看起来似乎很小,但以文本形式清晰阐述文档对您的工作效率有着很大的影响。
  • 文档是否完全自动生成?此类文档可能更难以理解,并且并非总是针对如何使用 API 提供明确的指导。
  • 相关文档是否是最新的?文档维护有时只是事后的补救措施。如果库更新了,但文档却没有,这可能会导致开发时间浪费。
  • 文档是否全面并且有多种格式?用户指南、示例代码、参考文档、现场演示和教程都是有价值的文档格式,可以帮助您成功使用库或框架。

文档并非总是完整的,这没关系。您需要评估组织的需求、项目要求以及软件的复杂性,然后据此确定所需的文档级别。

总结

首次选择库或框架时,感到不堪重负是正常现象。就像其他的一切一样,你学到的知识和练习得越多,你就会做得越好。当您下次选择要使用的库或框架时,参阅这篇博文可能会很有帮助。您可以将本博文中的标题用作核对清单。例如:此库是否性能出色?此库是否符合 Web 无障碍方面的业务标准?

您还可能需要考虑库和框架的其他方面,但本博文并未对其进行详细讨论:

  • 可扩展性:使用自定义逻辑和/或行为扩展库有多容易?
  • 工具:库是否具有代码编辑器插件、调试工具和构建系统插件等工具(如果适用)?
  • 架构:简洁的代码很重要,但库的整体架构是否合理?
  • 测试:项目是否有测试套件?项目网站是否使用测试套件通过最新提交的标记或指示器?
  • 兼容性:库与您当前使用的其他库和/或框架是否良好配合使用?
  • 费用:框架的费用是多少?它是开源的还是可供购买?
  • 个性化指标:此指标应位于条件列表的最下方,甚至可以完全忽略,但您可以考虑项目“投票”、代表项目的社交媒体帐号,和/或项目页面上待解决的错误/问题数量。