您是一名正在开发 “大型 JavaScript 应用程序” 的开发者,您在项目中发现了一些问题。 新团队成员难以找到所有内容的位置。 当您必须加载整个应用程序来测试一个组件时,调试问题很困难。 您的组件之间没有清晰的 API 边界,因此它们的实现细节相互渗透。 更新依赖项似乎是一项可怕的任务,因此您的应用程序无法利用最新的升级。
我们在 Bitovi 做出的一个关键认识是,“构建大型应用程序的秘诀是永远不要构建大型应用程序。” 当您将应用程序分解成更小的组件时,您可以更轻松地测试它们并将它们组装成更大的应用程序。 我们遵循我们称之为“modlet”的工作流,它提倡将您的每个组件构建成它们自己的小型应用程序,并附带自己的演示、文档和测试。
文章系列
- 构建大型 JavaScript 应用程序的关键:Modlet 工作流(您现在所处位置!)
- Modlet 工作流:使用 StealJS 改善您的开发工作流
遵循这种模式将
- 简化新开发人员的入门流程
- 帮助保持组件的文档和测试更新
- 改善您的调试和测试工作流
- 强制执行良好的 API 设计和关注点分离
- 使升级和迁移更容易
让我们逐一讨论这些优势,看看 modlet 工作流如何帮助您的开发团队提高效率。
简化新开发人员的入门流程
当新开发人员加入您的项目时,他们可能会被应用程序存储库中大量文件吓倒。 如果这些文件按类型组织(例如 CSS 文件夹、JS 文件夹等),那么他们将需要搜索多个文件夹才能找到与单个组件相关的所有文件。
遵循 modlet 工作流的第一步是为每个组件创建文件夹。 每个文件夹或modlet 应该包含该组件的所有文件,这样您的团队中的任何人都可以找到他们需要理解和开发组件所需的文件,而无需搜索整个项目。

此外,我们通过在它们的文件夹中包含以下至少这些文件,将 modlet 构建为它们自己的小型应用程序
- 主要源文件(JavaScript、样式表、模板等)
- 一个测试 JavaScript 文件
- 一个用于文档的 markdown 或文本文件(如果它们没有内嵌在您的代码中)
- 一个测试 HTML 页面
- 一个演示 HTML 页面
最后两个文件对于遵循 modlet 工作流至关重要。 首先,测试 HTML 页面用于在您的浏览器中加载组件的测试; 其次,演示 HTML 页面让您可以在浏览器中看到该组件,而无需加载整个应用程序。
改善您的调试和测试工作流
为每个组件创建演示和测试 HTML 页面可能看起来有点过分,但它们会为您的开发工作流带来一些重大改进。
演示 HTML 页面
- 让您无需加载整个应用程序即可快速查看该组件
- 为您提供了重现错误的起点(并减少了表面积)
- 为您提供了在多种场景中演示组件的机会
最后一点可以用几种方法来利用。 我曾在一些项目中工作过,我们
- 在一个页面上拥有同一组件的多个实例,这样我们就可以看到它在一些关键场景中的行为
- 使演示页面动态化,这样我们就可以使用数十个变量来测试组件
最后但同样重要的是,调试问题将更容易,因为组件与应用程序的其余部分隔离开。 如果你可以在组件的演示页面上重现问题,你就可以集中注意力,而不用考虑应用程序中无关的部分。
测试 HTML 页面为您提供了与演示 HTML 页面类似的优势。 当您只能运行单个组件的测试时,您
- 不需要用
.only
语句来填充您的测试代码,这些语句最终会被遗忘并在代码审查中被遗漏 - 可以更改组件并专注于该组件的测试,然后再运行应用程序的整个测试套件

强制执行良好的 API 设计和关注点分离
Modlet 工作流也促进了良好的 API 设计。 通过在至少两个地方使用每个组件(在您的应用程序中和在演示页面上),您将
- 考虑您的组件 API 所需的确切内容
- 在您的组件和应用程序的其余部分之间设置清晰的边界
如果您的组件 API 直观且无摩擦,那么为您的组件创建演示页面将毫无困难。 如果使用该组件需要太多“引导”,或者该组件与其使用方法之间没有清晰的分隔,那么您可能需要重新考虑它的架构方式。
使用清晰定义的组件 API,您就可以将组件从其原始存储库中提取出来,并在其他应用程序中使用。 如果您在一个大型公司工作,共享组件库对于快速开发项目非常有用。 Modlet 工作流鼓励您这样做,因为您的每个组件都已拥有自己的演示、文档和测试!
帮助保持组件的文档和测试更新
我在没有遵循 modlet 工作流的项目中看到的一个常见问题是文档和测试在主源文件更改时不会更新。 当团队遵循 modlet 工作流时,每个人都知道在哪里查找每个组件的文档和测试:它们与组件的源代码位于同一个文件夹中!
这使得识别缺失的文档和测试变得更容易。 此外,文件位于同一个文件夹中,提醒团队中的每个开发人员在更改该组件时更新它们。
这在代码审查期间也很有用。 大多数工具会按文件名列出文件,因此当您审查组件的更改时,会提醒您确保文档和测试也已更新。 此外,在实现和测试之间切换变得更加容易,因为它们会彼此靠近。

使升级和迁移更容易
最后但同样重要的是,遵循 modlet 工作流可以帮助您将应用程序升级到依赖项的新版本。 让我们考虑一个例子!
您选择的 JavaScript 框架发布了一个新的主要版本,您需要将应用程序迁移到新版本。 如果您遵循 modlet 工作流,您可以从更新不使用任何其他组件的组件开始进行迁移

单独的演示和测试页面对于进行此升级至关重要。 您可以先让组件的测试通过,然后使用演示页面对其进行视觉检查。
一旦这些组件正常工作,您就可以开始升级依赖于它们的组件

您可以继续执行此过程,直到使应用程序的所有组件都正常工作。 然后,剩下的就是测试实际应用程序,这将不那么令人畏惧,因为您知道各个组件正在正常工作。

当组件被包含且定义明确时,大型迁移会更容易。 正如我们在前面部分中讨论的那样,modlet 工作流鼓励清晰的 API 边界和关注点分离,这使得在隔离状态下测试组件变得更容易,从而使整个应用程序升级不那么令人畏惧。
立即在您的应用中使用 modlet 工作流程
您可以立即开始使用 modlet 工作流程。首先,如果您的团队仍然按文件类型进行组织,请开始按组件进行分组。将测试文件移动到您的组件文件夹,并为演示和测试您的组件添加一些 HTML 页面。您的团队可能需要花费一些时间来过渡,但从长远来看,这是值得的。
本文中的一些建议可能看起来很吓人,因为您的工具存在局限性。例如,如果您使用的是需要为每个页面创建单独包的模块加载器和捆绑器,那么为每个组件添加两个 HTML 页面将需要大量的构建配置。
在本系列的下一篇文章中,我们将讨论如何使用名为 StealJS 的模块加载器和捆绑器来加载每个组件的依赖项,而无需为每个 HTML 页面创建单独的构建。
请在评论中告诉我您的想法!如果您遵循类似的组织技术,请告诉我哪些有效,哪些无效。
文章系列
- 构建大型 JavaScript 应用程序的关键:Modlet 工作流(您现在所处位置!)
- Modlet 工作流:使用 StealJS 改善您的开发工作流
它就像 JavaScript 组件的组件库/样式指南?不错。
是的,我们的团队发现将演示作为 动态样式指南 的一部分非常有用。当您可以使用每个组件的示例进行操作时,组件库更容易理解!
我们也使用这种项目结构,发现它非常有用。如果您正在寻找利用这种结构来生成模式库/设计系统的工具,请查看 UIengine:https://github.com/dennisreimann/uiengine
我多年来一直使用这种模式,额外的工作总是证明从长远来看是值得的。另一个附带好处是,当您需要将组件发布到 npm 以便其他人可以使用时,所有必要的文件都已在一个地方进行组织。将组件拉到自己的目录中,初始化 git/npm 以及推送/发布通常只需要很少的工作量。
我在每个项目中都使用这种模式,它通过重用组件提高了我的生产力。
Angular、React 或其他流行框架已经强制开发人员按组件组织代码。在使用框架的情况下,使用原生 JavaScript 的用例和好处是什么?
以及缺点?
我已经有一些想法,但想听听您的经验。谢谢。
实际上没有任何框架“强制”任何人以任何特定方式组织代码,这与原生 JS 与框架无关。它仅仅是组织资产的一种模式。我在 ReactJS 项目、vue.js 项目、CanJS 项目和其他项目中使用过它。它将组件的所有资产整理到一个目录中:测试、演示、文档、css、模板、javascript 等。许多项目的组织方式是将所有模板放在一个文件夹中,css 放在另一个文件夹中,测试放在自己的文件夹中,文档放在另一个项目中,一个组件的所有部分最终分散开来。您可以将 modlet 模式视为一种方式,即您可以删除一个 modlet,并知道该特定组件的所有内容都已从项目中删除。
我认为您的库/框架选择完全取决于您的目标。我喜欢 modlet 工作流程的一点是,它不依赖于您使用什么框架。如果您将应用程序构建为组件集合,那么您就可以从为每个组件提供演示、测试等中获益。
是否可以在 webpack 中实现 modlet 工作流程,而不会损失 2 个月来设置配置文件?
我会让 webpack 用户介入来回答这个问题(是否有针对 Sean Larkin 的蝙蝠信号)?
本系列的 下一篇文章 讨论了 StealJS,您可以将其直接添加到现有项目中,仅用于演示和测试页面。
好吧,一些框架非常有主见(例如 ember),您必须在使用它时遵循其设计模式。无论如何,感谢您的澄清。我明白了你的意思。
喜欢这个概念。希望我能实现它!