选择 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 库有助于消除 Web 平台的怪异行为。图书馆也可以作为学习工具。例如,如果您不熟悉动画加/减速函数,库的源代码可以教您这些加/减速函数的工作原理。

有些库由大型公司提供支持,这些公司会投入时间和资金来确保库的安全性和最新性。许多库都附带详尽的文档,可让您和您的团队快速熟悉库的使用方法。

最终,使用 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 平台是否原生提供相同的功能。例如,Web 平台已经提供了颜色选择器,因此无需使用第三方 JavaScript 库来实现相同的功能。

安全

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

假设有一个发布到 NPM 生态系统的库。此类软件包可能是合法的。不过,随着时间的推移,软件包可能会遭到入侵。

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

  • 如果您使用 GitHub,请考虑使用代码的安全产品,例如 Dependabot。或者,考虑使用其他服务来扫描代码中的漏洞,例如 snyk.io。
  • 考虑使用代码审核服务,即由工程师组成的团队,他们可以手动审核您使用的第三方代码。
  • 评估是否应将依赖项锁定到特定版本,或在版本控制中提交第三方代码。这有助于将依赖项锁定到某个特定版本(该版本可能被视为安全版本)。讽刺的是,这可能会在安全性方面产生反作用,因为您可能会错过库的重要更新。
  • 浏览项目首页或 GitHub 页面(如有)。研究是否存在未解决的安全问题,以及之前的安全问题是否在合理的时间范围内得到了解决。
  • 与零依赖项的库相比,使用其他第三方代码的第三方代码可能带来更多风险。请注意此风险。

无障碍

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

基于 JavaScript 的客户端库(或框架)可以提高或降低网站的无障碍性。假设有一个第三方 JavaScript 库,可向网页添加图片滑块。如果图片滑块不考虑网络无障碍功能,您作为 Web 开发者可能会忽略这一重要功能,并发布缺少关键功能的产品,例如滑块无法通过键盘导航!

  • 自适应排版插件是否支持用户放大或缩小页面?
  • 文件上传器插件是否支持从辅助设备上传文件?
  • 动画库是否为偏好减少动画的用户提供支持?
  • 互动式地图插件是否支持仅使用键盘?
  • 音频播放器库是否在屏幕阅读器上提供适当的体验?

可以合理地预期,您(Web 开发者)需要一定程度的参与才能满足此类无障碍要求。例如:

  • 对于任何缺失的功能,您都可以在代码库中实现这些功能,即使继续使用相关库也是如此。
  • 在雇主的支持下,如果库作者允许,您可以向库贡献此类缺失的功能。
  • 您可以与库作者展开对话。例如,您的路线图中是否包含这些特定的无障碍功能?您是否同意这些内容应保留在媒体库中?
  • 对于热门应用场景,您可以探索更易于访问的替代库选项;这些选项可能存在,但更难找到。
  • 在极端情况下,您可能需要完全放弃某个库,并从头开始实现功能。如果库或框架在初次使用时无障碍体验不佳,您可能需要撤消库或框架原本免费提供的许多功能。

惯例

使用既定编码规范的软件库更易于使用。如果某个库使用的编码规范闻所未闻,那么您和您的团队可能很难使用该库。

如果某个库不遵循常见的编码规范(例如,常见的样式指南),您无法立即采取措施进行修复。不过,您仍有以下几种选择:

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

惯例在易用性方面发挥着重要作用。与需要进行大量实验才能弄清楚的反直觉 API 相比,包含直观 API 的库可以节省数小时甚至数天的人力。

更新

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

在选择库或框架时,请注意更新的处理方式,并注意这些决策可能会对您产生影响:

  • 该库是否有合理的发布时间表?例如,源代码库可能会频繁更新,但如果这些更新没有相应地“发布”或“发行”,您会发现很难下载这些更新。
  • 该库是否采用合理的软件版本控制方案来发布更新?库应该能为您节省时间。如果您每次更新库版本时都必须意外更改代码,这可能会违背最初使用该库的目的。破坏性更改有时不可避免,但在理想情况下,更改不应频繁发生,也不应强加给库使用者。
  • 该库是否致力于实现向后兼容性?有时,软件更新可能会带来破坏性更改,但也会提供一层向后兼容性。这样,库使用者只需对代码进行极少的更改,即可使用最新的库版本。

许可

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

例如,某个 JavaScript 库可能具有软件许可,允许您在非商业目的环境中使用该库。对于个人兴趣爱好项目,这可能是一个不错的选择。如果您的项目具有商业元素,则您可能需要考虑企业许可。

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

社区

拥有庞大用户/贡献者社区的库或框架可能会带来好处,但并不能保证一定如此。一般来说,库或框架的用户越多,就越有可能受益。请考虑参与开发者社区的以下优缺点:

优点:

  • 庞大的用户群可能意味着,您有更多机会尽早且经常发现 bug。
  • 活跃的大型社区可能意味着有更多关于相关库或框架的教程、指南、视频,甚至课程。
  • 活跃的大型社区可能意味着论坛和问答网站上会有更多支持,从而增加支持问题得到解答的可能性。
  • 活跃的社区意味着会有更多外部贡献者参与到库或框架的开发中。它们可以帮助提供作者路线图中未包含的功能。
  • 如果某个库或框架在社区中很受欢迎,那么您的同行和同事很可能听说过甚至熟悉该库或框架。

缺点:

  • 如果一个项目拥有庞大且多样化的用户群,那么不断添加功能可能会导致项目变得臃肿。臃肿的库可能会损害网站性能。
  • 如果项目拥有活跃且参与度高的社区,作者和维护者可能会面临压力,并且可能需要进行大量的社区管理。
  • 如果一个项目发展迅速,但没有得到适当的支持,就可能会开始出现社区环境恶化的迹象。例如,初级或初级 Web 开发者可能会因为守门而感到在某个社区不受欢迎。

文档

无论 JavaScript 库或框架多么简单或复杂,软件文档始终能提供帮助。即使是经验丰富的开发者,也会使用文档,而不是自己去琢磨代码。文档会说明您应该使用的 API 以及使用方式。

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

  • 该库是否包含文档?如果不是,您需要能够自行解决问题。
  • 文档是否清晰、易懂且无歧义?许多开发者在文档上花费了大量时间。这看似微不足道,但清晰的文本记录对工作效率的影响不容小觑。
  • 文档是完全自动生成的吗?此类文档可能更难理解,并且不一定能提供有关如何使用 API 的明确指导。
  • 文档是否为最新版本?文档维护有时会被视为事后工作。如果库已更新,但文档未更新,则可能会浪费开发时间。
  • 文档是否全面且提供多种格式?用户指南、示例代码、参考文档、实时演示和教程都是非常有价值的文档格式,可以帮助您成功使用库或框架。

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

总结

首次选择库或框架时,感到不知所措是正常的。就像其他任何事情一样,您对某项任务的学习和练习越多,您就会做得越好。下次选择要使用的库或框架时,不妨参考一下这篇博文。您可以将本文中的标题用作核对清单。例如:此库是否高效?此库是否符合我的业务在网络无障碍方面的标准?

您可能还需要考虑库和框架的其他方面,本文未对此进行深入讨论:

  • 可扩展性:使用自定义逻辑和/或行为扩展库的难易程度如何?
  • 工具:如果适用,该库是否具有代码编辑器插件、调试工具和构建系统插件等工具?
  • 架构:干净的代码很重要,但库的整体架构是否合理?
  • 测试:项目是否有测试套件?项目网站是否使用徽章或指示器来表明测试套件正在针对最新提交进行测试?
  • 兼容性:该库是否能与您当前使用的其他库和/或框架很好地协同工作?
  • 成本:框架的成本是多少?它是开源的还是可供购买的?
  • 虚荣指标:这些指标在您的标准列表中应该排在较低的位置,甚至完全忽略,但您可能需要考虑项目“投票”、代表项目的社交媒体账号和/或项目页面上有多少未解决的 bug/问题。