本文将分享一些有益的见解,帮助您选择要在 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 库来制作动画。某些库可能会轻松增加几十千字节,在某些情况下甚至会增加数百千字节。由于浏览器需要下载、解析、编译和执行代码,因此此类 JavaScript 资源可能会导致网页加载延迟。
JavaScript 库越大,对用户的性能影响就越大。
在评估或使用 JavaScript 库或框架时,请考虑以下建议来提高性能:
- 如果使用的是大型 JavaScript 库,请考虑使用功能相当且规模较小的库替代。例如,与某些其他选项相比,date-fns 提供的功能很多,但大小更合理。
- 接着上一个 date-fns 示例,仅导入所需的函数,例如:
import { format } from 'date-fns'
。请务必将此方法与树摇动结合使用,以便构建最小的 JavaScript 载荷并将其发送给用户。 - 使用 Lighthouse 等性能测试工具观察使用特定 JavaScript 库的性能影响。如果某个库会使网页加载时间延长一秒(请务必在测试期间节流网络和 CPU),那么您可能需要重新评估所选库。除了检查网页加载情况外,请务必分析调用相关库中代码的任何网页行为,因为网页加载性能并不能说明所有问题。
- 如果库作者欢迎您提供反馈,请向项目提交性能观察结果、建议,甚至贡献。这正是开源社区大显身手的地方!如果您决定捐款,则可能需要先与您的雇主确认。
- 使用自动化软件包跟踪工具(例如 bundlesize)监控库的意外大型更新。JavaScript 库通常会随着时间的推移而增长。添加功能、修复 bug、边界情况等都会增加库的文件大小。在您/您的团队同意使用某个库后,更新该库可能就不会那么麻烦,而且可能不会引发太多问题。这时,自动化操作会很有用。
- 查看您对库的要求,并评估 Web 平台是否原生提供相同的功能。例如,Web 平台已提供颜色选择器,因此无需使用第三方 JavaScript 库即可实现相同的功能。
安全
使用第三方模块会带来一些固有安全风险。Web 应用代码库中的恶意软件包可能会危害开发团队和用户的安全。
假设有一个发布到 NPM 生态系统的库。此类软件包可能是合法的。不过,随着时间的推移,该软件包可能会遭到入侵。
在使用或评估第三方代码时,请考虑以下安全提示:
- 如果您使用 GitHub,请考虑使用代码的安全产品和服务,例如 Dependabot。或者,考虑使用其他服务来扫描代码中的漏洞,例如 snyk.io。
- 不妨考虑使用代码审核服务,由工程师团队手动审核您使用的第三方代码。
- 评估您是否应将依赖项锁定到特定版本,或者将第三方代码提交到版本控制系统中。这有助于将依赖项锁定到一个特定版本(该版本应该被视为安全)。具有讽刺意味的是,这可能会对安全性产生反作用,因为您可能会错过库的重要更新。
- 浏览项目首页或 GitHub 页面(如果有)。调查是否存在未解决的安全问题,以及之前的安全问题是否在合理的时间范围内得到了解决。
- 与没有任何依赖项的库相比,使用其他第三方代码的第三方代码可能会带来更大的风险。请注意这一风险。
无障碍
您可能想知道软件库与网站无障碍功能有何关联。虽然软件库可以在不同的环境中使用,但在基于 JavaScript 的客户端库中,网络无障碍至关重要。
基于 JavaScript 的客户端库(或框架)可能会提高或降低您网站的无障碍功能。假设有一个第三方 JavaScript 库,用于向网页添加图片滑块。如果图片滑块未考虑到无障碍网页设计,您作为 Web 开发者可能会忽略这一重要功能,并发布缺少关键功能(例如滑块可通过键盘导航)的产品!
- 响应式排版插件是否支持用户缩放网页?
- 文件上传器插件是否支持通过辅助设备上传文件?
- 动画库是否支持偏好减少动作的用户?
- 交互式地图插件是否支持仅使用键盘?
- 音频播放器库是否在屏幕阅读器上提供适当的体验?
我们合理地预计,您(网站开发者)需要参与到一定程度,才能满足此类无障碍要求。例如:
- 对于缺少的任何功能,您都可以在代码库中实现这些功能,即使继续使用相关库也是如此。
- 在雇主的支持下,如果库作者允许,您可以向库贡献缺少的功能。
- 您可以与库作者展开对话。例如,您的路线图中是否包含这些特定的无障碍功能?您是否同意将这些内容保留在图书馆中?
- 对于常见的用例,您可以探索更易于访问的替代库选项;这些库可能存在,但更难找到。
- 在极端情况下,您可能需要完全舍弃某个库,并从头开始实现功能。如果库或框架在首次使用时降低了无障碍体验,并且您需要撤消库或框架应该免费提供的许多功能,就可能会发生这种情况。
惯例
使用已建立的编码规范的软件库更易于使用。如果某个库使用的是闻所未闻的编码规范,那么您和您的团队可能很难使用这样的库。
如果库不遵循常见的编码规范(例如常见的样式指南),您无法立即采取有效的措施来解决问题。不过,您仍然可以通过以下几种方式来解决此问题:
- 请务必区分库源代码和向库用户公开的 API。虽然内部源代码可能使用不熟悉的惯例,但如果 API(您与之互动的库部分)使用熟悉的惯例,则可能无需担心。
- 如果库 API 不遵循常见的编码规范,您可以使用 JavaScript 设计模式(例如代理模式),将与库的所有交互封装并包含在代码库中的单个文件中。这样,您的代理便可以向代码库中的其他代码部分提供更直观的 API。
惯例在易用性方面发挥着重要作用。与需要大量实验才能弄明白的反直觉 API 相比,包含直观 API 的库可以节省数小时甚至数天的人力。
更新
例如,对于执行一些数学计算的完全正常运行的库,此类库可能很少需要更新。事实上,在瞬息万变的 Web 开发领域,功能齐全的库是可遇不可求的!不过,有时您希望库作者能够及时回复并愿意进行更新。新的研究和发现可能会揭示更好的做事方法,因此库和框架中使用的技术始终会发生变化。
选择库或框架时,请注意更新的处理方式,并注意此类决策可能会影响您:
- 该库是否有合理的发布时间表?例如,源代码代码库可能会经常更新,但如果此类更新未相应地“发布”或“发布”,您会发现下载此类更新可能很困难。
- 库版本更新是否采用合理的软件版本控制方案?库应该能为您节省时间。如果您每次更新库版本时都必须意外更改代码,这可能会使使用该库的初衷落空。有时无法避免破坏性更改,但在理想情况下,更改不应频繁发生,也不应强加给库使用方。
- 该库是否在向后兼容性方面投入了精力?有时,软件更新可能会带来破坏性更改,但同时也会提供一层向后兼容性。这样一来,库使用方只需对其代码进行最少的更改,即可使用最新的库版本。
许可
软件许可是使用第三方软件库的重要方面。库作者可以为其库分配许可。如果您考虑使用该库,则其许可选项可能会对您产生影响。
例如,某个 JavaScript 库的软件许可可能允许您在非商业环境中使用该库。对于个人爱好项目,这可能是一个不错的选择。如果您的项目包含商业元素,则可能需要考虑使用企业许可。
如有疑问,请考虑寻求专业法律建议,或咨询贵公司内的法律团队。
社区
拥有庞大用户/贡献者社区的库或框架可能有益,但这并不保证一定如此。一般来说,库或框架的用户越多,受益的可能性就越大。请考虑加入开发者社区的利弊:
优点:
- 用户群越大,就越有可能尽早发现 bug 并及时解决。
- 活跃的大型社区可能意味着有关相关库或框架的更多教程、指南、视频甚至课程。
- 活跃的大型社区可能意味着论坛和问答网站上有更多支持人员,从而提高支持问题得到解答的可能性。
- 活跃的社区意味着该库或框架有更多外部贡献者。他们可以帮助实现作者路线图中未涵盖的功能。
- 如果某个库或框架在社区中广受欢迎,那么您的同行和同事就更有可能听说过或甚至熟悉这种库或框架。
缺点:
- 拥有庞大且多元化用户群的项目可能会因不断添加功能而变得臃肿。过大的库可能会影响网站性能。
- 如果项目拥有活跃且互动度高的社区,可能会给作者和维护者带来压力,并且可能需要进行大量的社区管理。
- 如果项目发展迅速,但没有提供适当的支持,就可能会开始出现有毒社区的迹象。例如,初级或新手 Web 开发者可能会因门槛过高而感到不受某个社区欢迎。
文档
无论 JavaScript 库或框架有多简单或多复杂,软件文档总能派上用场。即使是经验丰富的开发者,也都会使用文档,而不是自行弄清楚代码。文档会明确说明您应使用哪些 API 以及如何使用这些 API。
文档甚至可以提供示例代码,让您更轻松地快速上手。评估库或框架时,您可以问一些以下问题:
- 该库是否包含文档?如果没有,您需要能够自行解决问题。
- 文档是否清晰、易懂且没有歧义?许多开发者都花费大量时间来编写文档。这可能看起来不起眼,但文本文档的清晰度可能会对您的工作效率产生很大影响。
- 文档是完全自动生成的吗?此类文档可能更难以理解,并且并不总能就如何使用 API 提供明确的指导。
- 文档是否是最新的?文档维护有时会被视为次要任务。如果库更新了,但文档没有更新,可能会导致浪费开发时间。
- 文档是否全面且提供多种格式?用户指南、示例代码、参考文档、实时演示和教程都是有价值的文档格式,可帮助您成功使用库或框架。
文档不可能总是完整无缺,这没关系。您需要评估贵组织的需求、项目要求和软件的复杂性,并据此确定所需的文档级别。
总结
首次选择库或框架时,感到不知所措是正常的。就像其他一切一样,您越学习和练习某项任务,就会越熟练。下次选择要使用的库或框架时,不妨参阅这篇文章。您可以将本文中的标题用作核对清单。例如:此库是否高效?此库是否符合我的企业在 Web 无障碍方面的标准?
您可能还需要考虑库和框架的其他方面,而本文并未详细讨论这些方面:
- 可扩展性:使用自定义逻辑和/或行为扩展库的难易程度如何?
- 工具:如果适用,该库是否提供代码编辑器插件、调试工具和构建系统插件等工具?
- 架构:干净的代码很重要,但库的整体架构合理吗?
- 测试:项目是否包含测试套件?项目网站是否使用了测试套件针对最新提交通过测试的标记或指示器?
- 兼容性:该库能否与您当前使用的其他库和/或框架良好协作?
- 费用:框架的费用是多少?该应用是开源的还是可供购买的?
- 虚荣指标:这应该在标准列表中排在靠后的位置,甚至可以完全忽略,但您可以考虑项目“投票数”、代表项目的社交媒体账号,以及/或者项目页面上有多少未解决的 bug/问题。