构建和维护 OUI(Optimizely 的 UI 库):第 2/2 部分

Avatar of Daniel O'Connor
Daniel O'Connor 发表

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

以下是 Daniel O’Connor 的客座文章。Daniel 分享了更多关于 OUI 的信息,OUI 是 Optimizely 的 UI 库,由 Tom Genoni第 1 部分 中介绍。

一年前,我们在 Optimizely 启动了一项任务,旨在统一我们的产品设计并控制我们不断增长的 CSS 负载。UI 工程师 Tom Genoni 于 2014 年率先开展了这项工作,并创建了 我们名为 OUI 的 Sass 框架

我们首先将 OUI 集成到 Optimizely 应用程序的一小部分中,并在接下来的几个月中逐渐将其添加到整个 A/B 测试产品中。此后,我们使用该框架开发了一个全新的产品和一些较小的产品。范围的扩大带来了独特的挑战,并要求我们改进实施策略。

第 1 部分 中,Tom 撰写了构建和推广 OUI 所需的高级步骤。在这篇文章中,我将讨论我们做出的 Sass 架构决策以及我们添加的流程,这些流程使我们能够扩展 OUI。

OUI 的结构

OUI 是在 Optimizely 代码库之外创建的,并位于 GitHub 上的自己的存储库中。该架构允许开发人员通过覆盖变量轻松修改默认样式,并创建与框架完美配合的部分(组件和对象)。

根 `my_app.scss` 文件组合了来自 OUI 和本地项目的变量和部分。

上图显示了我们通常如何将 OUI 集成到应用程序中。在实践中,`my_app.scss` 文件通常如下所示

// [1] Import OUI and app functions and mixins
@import 'oui/partials/elements/functions';
@import 'oui/partials/elements/mixins';
@import 'my_app/partials/elements/functions';
@import 'my_app/partials/elements/mixins';

// [2] Import OUI and app variables
@import 'oui/oui-variables';
@import 'my_app/my_app-variables'; 

// [3] Import OUI and app partials
@import 'oui/oui-partials';
@import 'my_app/my_app-partials'; 

// [4] Import OUI trumps
@import 'oui/partials/trumps/background';
@import 'oui/partials/trumps/borders';
@import 'oui/partials/trumps/layo	ut';
@import 'oui/partials/trumps/margin';
@import 'oui/partials/trumps/padding';
@import 'oui/partials/trumps/sizing';
@import 'oui/partials/trumps/type';

关于上述 SCSS 的一些说明

  1. 我们首先导入 OUI 的 mixin 和函数,然后导入我们需要的任何自定义函数。
  2. OUI 的变量在我们的应用程序变量之前加载。这使我们能够修改或覆盖现有变量并引入自定义变量。
  3. 这是文件的核心内容。第一个部分导入所有 OUI 的基础规则、组件和对象,而第二个部分导入特定于我们产品的代码。通过在此处列出它们,我们确保它们获取所有默认变量以及我们的应用程序变量添加或更改的任何变量。
  4. Trumps(我们的实用程序类)最后加载,因为它们执行特定的工作,不应被覆盖。

版本 1:使用 npm 基本集成 OUI

在 GitHub 上托管 OUI 使我们能够使用 npm 将其轻松集成到项目中,最初我们仅使用它来提取来自 GitHub 的最新 OUI 提交,这些提交可在 Optimizely 应用程序中使用。

npm install --save git://github.com/optimizely/oui.git#commit-hash

实际上,任何 GitHub 存储库都可以使用此方法安装为依赖项。指定提交哈希值是一种轻量级的方法,可以防止 OUI 中的重大更改自动被提取。使用此过程,`my_app.scss` 中对 OUI 的引用指向 `node_modules/` 目录,这是 npm 的默认安装位置。

// Before:
@import 'oui/partials/elements/functions';

// After:
@import 'path/to/node_modules/oui/partials/elements/functions';

或者,我们可以将 `oui/` 符号链接到 `path/to/node_modules/oui/`。

这种基本方法运行了几个月,但随着我们开始将 OUI 添加到其他项目中,问题出现了。应用程序如何才能自动提取 OUI 错误修复和其他非重大更改?如何在升级到新版本的 OUI 时提供上下文?如何在快速移动的同时保持文档最新?我们知道我们可以做得更好!

版本 2:OUI 的高级实现

为了使 OUI 真正强大且对开发人员友好,我们在之前工作的基础上,利用了一些技术工具和最佳实践。尽管这些步骤比较高级,但我们发现它们是必不可少的。

  1. 使用 npm 和语义版本控制
  2. 添加更改日志
  3. 实施构建系统
  4. 创建动态文档解决方案

版本控制

OUI 已经开发了一年多,但重大更改仍然很常见。重大更改(例如 重命名 flexbox 类)可能需要花费数小时的仔细查找和替换才能在大型代码库中得到支持。

如前所述,我们最初使用 npm 从 GitHub 中提取 OUI,并包含一个提交哈希值以防止重大更改自动获取。此解决方案速度较慢,因为对于每个新更改,都需要在应用程序的 `package.json` 中更新提交哈希值。理想情况下,向后兼容的更改(例如错误修复和新组件)应该自动提取。

我们通过在 npm 上发布 OUI、遵循 语义版本控制我们的版本号 中,以及 配置 NPM 以接受次要和修补程序更改 来实现这一点。OUI 的贡献者会识别重大更改并相应地更改版本号。

维护更改日志

在没有上下文或清晰的版本说明的情况下,升级到项目的最新版本 OUI 可能很困难。我们创建了 更改日志(基于 Keep a Changelog)来跟踪所有提交和拉取请求。这使得生成有用的 版本说明 变得容易,这些说明可以帮助实施 OUI 的开发人员准确地了解在升级完整版本时需要修复或更改的内容。

使用 Travis CI 进行 SCSS 代码风格检查和编译

我们使用 scss-lint 维护一致的风格,并运行 node-sass 以确保 SCSS 编译。我们已使用 GitHub 的 Travis CI 集成将基本代码风格检查和编译检查集成到 GitHub 拉取请求中。

这确保了代码的整洁,并防止合并明显的错误。它还具有自动化代码审查过程一部分的额外好处,使审查人员能够专注于重要部分。

创建动态文档

我们有数十位工程师使用 OUI。为了确保每个人都能使用该框架,我们必须拥有记录良好的代码。我们使用 ScribeSass(一个内部构建的 node.js 模块)根据 SCSS 文件代码中的注释自动生成一个文档网站(尚未上线)。我们很快就会将其作为开源项目发布。


我们在一年多前将 OUI 引入 Optimizely 代码库。使 OUI 灵活的架构决策以及对工具和流程的投资使我们能够将其集成到五个存储库中,轻松地让新的贡献者加入,并使软件工程师团队能够编写 HTML 而无需引入新的 CSS。

我们鼓励您在 GitHub 上浏览存储库,阅读我们的 CONTRIBUTING.mdREADME.md 文件,并提出您的问题!