一、Bower

Electronic supplementary material The online version of this chapter (doi:10.​1007/​978-1-4842-0662-1_​1) contains supplementary material, which is available to authorized users.

伟大的事情是由一系列小事情集合起来完成的。—文森特·梵高

包管理的概念,也称为依赖性管理,并不新鲜。此类别中的工具为开发人员提供了一种管理项目所依赖的各种第三方库的机制。广泛使用的例子包括

  • NPM:node . js 的包管理器
  • composer:PHP 中的依赖管理工具
  • pip:PyPA 推荐的安装 Python 包的工具
  • NuGet:微软开发平台的包管理器,包括。网

虽然包管理并不是一个新概念,但是最近才开始被广泛采用的一个实践是将这一概念应用于前端 web 素材的管理,这些素材是作为现代 web 应用的构建块的 JavaScript 库、样式表、字体、图标和图像。随着构建现代 web 应用的基础变得越来越复杂,对这种结构的需求变得越来越明显。曾经依赖于一小部分定义广泛的“一刀切”的第三方库(例如 jQuery)的 Web 应用,现在发现自己正在使用许多更小的库,每个库都有严格定义的用途。这种方法的好处包括更小的模块更容易测试,以及父应用的灵活性更高,可以更容易地扩展第三方库或在必要时完全替换它们。

本章旨在帮助您快速入门并使用 Bower,这是一个前端包管理器,其根源在于 Twitter 的开源计划。涵盖的主题包括

  • 安装和配置 Bower
  • 将 Bower 添加到项目中
  • 查找、添加和删除包
  • 语义版本控制
  • 管理依赖链
  • 创建 Bower 包

入门指南

与 Bower 的所有交互都通过命令行工具进行,该工具可以通过 npm 安装。如果您还没有安装 Bower,那么您应该在继续之前安装它,如清单 1-1 所示。

Listing 1-1. Installing the bower Command-Line Utility via npm

$ npm install -g bower

$ bower --version

1.3.12

Note

Node 的软件包管理器(npm)允许用户在两种环境中安装软件包:本地或全局。在本例中,bower安装在全局上下文中,该上下文通常是为命令行工具保留的。

配置 Bower

Bower 是通过一个(可选的)JSON 文件基于每个项目进行配置的,该文件存在于项目的根文件夹.bowerrc中。出于介绍的目的,我们将只查看这个文件中最频繁更改的设置(参见清单 1-2 )。

Listing 1-2. The .bowerrc File from This Chapter’s Sample Project

// example-bootstrap/.bowerrc

{

"directory": "./public/bower_components"

}

默认情况下,Bower 会将项目的依赖项存储在bower_components文件夹中。您可能想要更改这个位置,而directory设置允许您这样做。

清单

Bower 为开发人员提供了一个单一的入口点,从这里可以找到、添加、升级和删除第三方库。随着这些动作的发生,Bower 用项目依赖项的最新列表更新一个被称为“manifest”的 JSON 文件。清单 1-3 显示了本章示例项目的 Bower 清单。在这个例子中,Bower 意识到了一个单一的依赖,即引导 CSS 框架。

Listing 1-3. Bower Manifest for This Chapter’s Sample Project

// example-bootstrap/bower.json

{

"name": "example-bootstrap",

"version": "1.0.0",

"homepage": "https://github.com/username/projectT2】

"authors": [

"John Doe <john.doe@gmail.com>"

],

"dependencies": {

"bootstrap": "3.2.0"

}

}

如果我们通过删除public/bower_components文件夹意外地删除了我们项目的所有依赖项,我们可以通过发出一个命令很容易地将我们的项目恢复到它以前的状态,如下所示。这样做会导致 Bower 将其清单与我们项目的当前文件结构进行比较,确定缺少哪些依赖项,并恢复它们。

$ bower install

这种行为的结果是,我们可以选择在版本控制中忽略项目的/public/bower_components文件夹。通过只提交 Bower 的清单,而不是依赖项本身,我们项目的源代码可以保持在一个更干净的状态,只包含与我们自己的工作直接相关的文件。

Note

对于将项目的依赖关系置于版本控制之外是否是一个好主意,人们有不同的看法。一方面,这样做会产生一个更干净的存储库。另一方面,这也打开了潜在问题的大门。)遇到连接问题。普遍的共识似乎是,如果您正在处理一个“可部署的”项目(例如,一个应用,而不是一个模块),提交您的依赖项是首选的方法。否则,将项目的依赖项置于版本控制之外可能是个好主意。

创建新清单

当您第一次在项目中使用 Bower 时,通常最好让 Bower 为您创建一个新的清单,如下所示。之后,如果需要,您可以进一步修改它。

$ bower init

查找、添加和删除 Bower 包

Bower 的命令行工具为定位、安装和删除软件包提供了许多有用的命令。让我们看看这些命令是如何帮助简化管理项目外部依赖关系的过程的。

查找包

Bower 改进您的开发工作流程的主要方法之一是为您提供一个集中的注册表,从中可以找到第三方库。要搜索 Bower 注册表,只需将search参数传递给 Bower,后跟要搜索的关键字,如清单 1-4 所示。在本例中,只显示了返回的搜索结果列表中的一小段摘录。

Listing 1-4. Searching Bower for jQuery

$ bower search jquery

Search results:

jquery git://github.com/jquery/jquery.git

jquery-ui git://github.com/components/jqueryui

jquery.cookie git://github.com/carhartl/jquery-cookie.git

jquery-placeholder git://github.com/mathiasbynens/jquery-placeholder.git

添加包

每个搜索结果都包括注册软件包的名称,以及可以直接访问它的 GitHub 存储库的 URL。一旦我们找到了想要的包,我们就可以将它添加到我们的项目中,如清单 1-5 所示。

Listing 1-5. Adding jQuery to Our Project

$ bower install jquery --save

bower jquery#*            cached git://github.com/jquery/jquery.git#2.1.3

bower jquery#*          validate 2.1.3 against git://github.com/jquery/jquery.git#*

bower jquery#>= 1.9.1     cached git://github.com/jquery/jquery.git#2.1.3

bower jquery#>= 1.9.1   validate 2.1.3 against git://github.com/jquery/jquery.git#>= 1.9.1

bower jquery#>= 1.9.1     cached git://github.com/jquery/jquery.git#2.1.3

bower jquery#>= 1.9.1   validate 2.1.3 against git://github.com/jquery/jquery.git#>= 1.9.1

bower jquery#>= 1.9.1    install jquery#2.1.3

jquery#2.1.3 public/bower_components/jquery

Note

Bower 不托管任何与其注册表中包含的包相关联的文件;它让 GitHub 来承担这个责任。虽然可以在任何 URL 托管包,但是大多数公共包都可以在 GitHub 上找到。

请注意,在清单 1-5 中,我们将--save选项传递给了 Bower 的install命令。默认情况下,install命令会将请求的包添加到一个项目中,而不会更新它的清单。通过传递--save选项,我们指示 Bower 将这个包永久存储在其依赖项列表中。

清单 1-6 显示了本章示例项目中的 HTML。通过 Bower 将 jQuery 添加到我们的项目后,我们可以像加载任何其他库一样,通过一个script标签来加载它。

Listing 1-6. HTML from Our Sample Project That References the jQuery Package Just Added

// example-jquery/public/index.html

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="utf-8">

<meta http-equiv="X-UA-Compatible" content="IE=edge">

<meta name="viewport" content="width=device-width, initial-scale=1">

<title>Bower Example</title>

</head>

<body>

<div id="container"></div>

<script src="/bower_components/jquery/dist/jquery.min.js"></script>

<script>

$(document).ready(function() {

$('#container').html('<p>Hello, world!</p>');

});

</script>

</body>

</html>

开发依赖性

默认情况下,Bower 安装的任何包都被认为是“生产”依赖项,但是这种行为可以通过传递--save-dev选项来覆盖。这样做会将所有已安装的软件包标记为“开发”依赖项。此类包仅用于开发目的,而非项目的最终用户。

一旦我们准备好将应用部署到生产环境中,我们就可以指示 Bower 只安装生产依赖项,如下所示,从而产生一个更精简的版本,其中不包含最终用户不感兴趣的无关文件。

$ bower install -- production

移除包

移除 Bower 包的过程很简单。和前面的例子一样,我们传递--save参数来更新 Bower 的清单,以反映这一变化:

$ bower uninstall jquery --save

语义版本控制

如果您要安装 jQuery(如清单 1-5 所示),然后查看项目的 Bower 清单的内容,您会看到类似于清单 1-7 的内容。

Listing 1-7. Semantic Version (Semver) Number

"dependencies": {

"jquery": "∼2.1.3"

}

我们在清单 1-7 中看到的版本号 2.1.3(暂时忽略字符)就是所谓的语义版本号(简称 semver)。语义版本化是一种标准,它描述了一种通用格式,开发人员可以使用这种格式为他们的项目分配版本号。格式如下所示:

Version X.Y.Z (Major.Minor.Patch)

语义版本化格式要求开发人员创建明确定义的(通过文档或者通过清晰的、自文档化的代码)API,为用户提供进入库的单一入口点。刚刚起步的新项目通常从版本 0.0.0 开始,并随着新版本的创建而逐步升级。版本号低于 1.0.0 的项目被认为是处于重度开发中,因此,允许对其 API 进行大范围的更改,而不改变其主要版本号。但是,版本号为 1.0.0 或更高版本号的项目受以下一组规则的指导,这些规则决定了应如何更改版本号:

  • 当更新导致用户在以前版本中与项目 API 的交互方式发生重大变化时,项目的主版本号应该发生变化。
  • 当新特性以向后兼容的方式添加到项目中时,项目的次版本号应该改变(即,现有的 API 没有被破坏)。
  • 当引入向后兼容的错误修复时,项目的补丁版本号应该改变。

这些规则为开发人员提供了对任何两个版本之间发生的变化程度的洞察。随着我们的 Bower 清单的增长,以及我们开始向我们的项目添加越来越多的依赖项,这样的洞察力将会被证明是有用的。

Note

清单 1-7 中显示的字符告诉 Bower,无论何时运行install命令,都允许自动安装“相对接近”版本 2.1.3 的 jQuery 未来版本。如果在同一个句子中使用短语“相对接近”和“自动安装”让你毛骨悚然,你并不孤单。最佳实践建议您在引用 Bower 的依赖项时避免使用“∨X . y . z”格式。相反,您最好指定希望包含在项目中的依赖项的确切版本。随着未来更新的发布,您可以手动检查它们,并自行决定是否以及何时更新。本章后面的例子将遵循这个建议。

管理依赖链

开发人员从使用 Bower 中获得的主要好处之一是可以轻松地监控和集成对项目整个依赖链的更新。为了说明这一点,让我们看看本章的示例项目中包含的依赖项列表(参见清单 1-8 )。

Listing 1-8. Installing and Listing the Various Bower Packages Required by Our Sample Project

$ bower install

bower bootstrap#3.2.0     cached git://github.com/twbs/bootstrap.git#3.2.0

bower bootstrap#3.2.0   validate 3.2.0 against git://github.com/twbs/bootstrap.git#3.2.0

bower jquery#>= 1.9.0     cached git://github.com/jquery/jquery.git#2.1.3

bower jquery#>= 1.9.0   validate 2.1.3 against git://github.com/jquery/jquery.git#>= 1.9.0

bower bootstrap#3.2.0    install bootstrap#3.2.0

bower jquery#>= 1.9.0    install jquery#2.1.3

bootstrap#3.2.0 public/bower_components/bootstrap

ε──t0″

jquery#2.1.3 public/bower_components/jquery

$ bower list

bower check-new     Checking for new versions of the project dependencies..

example-bootstrap#1.0.0 /opt/example-bootstrap

ε□□□□□□□□□□□

ε──t0″

多亏了 Bower,我们现在有了一个简单的图表来描述我们的项目所依赖的外部依赖,以及它们之间的关系。我们可以看到,我们有一个 Bootstrap 依赖项,它又有自己对 jQuery 的依赖项。Bower 还打印当前安装的每个组件的特定版本。

Note

许多第三方库不是完全独立的,它们有自己的依赖项。Bootstrap(依赖于 jQuery)就是这样一个例子。当添加这样一个包时,Bower 足够聪明,能够识别这些额外的依赖项,如果它们不存在的话,它会主动将它们添加到您的项目中。然而,需要注意的是,与更复杂的包管理器(例如 npm)不同,Bower 将所有的包存储在一个平面文件夹结构中,这意味着如果不小心的话,您会偶尔遇到版本冲突。

在清单 1-8 中,Bower 告诉我们,比我们的项目目前所依赖的版本(3.2.0)更新的 Bootstrap 版本(3.3.2)已经可用。我们可以通过修改我们项目的清单来引用这个新版本,并重新运行install命令来更新这个依赖,如清单 1-9 所示。

Listing 1-9. Installing Bower Packages After Having Updated the Version of jQuery Our Project Relies On

$ bower install

bower bootstrap#3.3.2     cached git://github.com/twbs/bootstrap.git#3.3.2

bower bootstrap#3.3.2   validate 3.3.2 against git://github.com/twbs/bootstrap.git#3.3.2

bower bootstrap#3.3.2    install bootstrap#3.3.2

bootstrap#3.3.2 public/bower_components/bootstrap

ε──t0″

创建 Bower 包

到目前为止,我们的重点是将 Bower 集成到我们自己的项目中。我们已经在我们的项目中初始化了 Bower,并且发现了我们可以如何查找、添加和删除包。然而,在某一点上,你会希望发现自己想要与他人共享自己的包。为此,您需要确保遵循一些简单的准则,从选择有效的名称开始。

选择一个有效的名称

您需要为您的包选择一个在 Bower 的公共注册表中唯一的名称。使用 Bower 的search命令来查找您想要的名称是否可用。其他要求包括

  • 该名称应为“slug”格式;比如my-unique-project
  • 名称应该全部小写。
  • 只允许字母数字字符、点和破折号。
  • 该名称应以字母字符开头和结尾。
  • 不允许连续的点和破折号。
  • 确定名称后,相应地更新项目的bower.json文件的内容。

使用 Semver Git 标签

在本章的前面,我们看了一下语义版本化的概念,这是一个为项目分配有意义的版本号的通用标准。您将希望确保您遵循这个标准,因为这将允许您的软件包的消费者跟踪和集成您未来的更改。

如果您想要共享的包刚刚开始,合适的版本号应该是 0.0.0。当您提交将来的更改并创建新的版本时,您可以根据更新的程度适当地增加该值。当您确定您的项目已经达到了它的第一个“稳定的”里程碑时,将您的版本号更新到 1.0.0 来反映这种状态。

你的项目的每个版本号在 GitHub 上都应该有一个对应的标签。正是 GitHub 标签和您的包的版本之间的这种关系允许消费者在他们的项目中引用特定的版本。

假设您已经将代码提交给 GitHub,参见清单 1-10 中的示例,了解如何创建您的第一个标签。

Listing 1-10. Creating Your First Semver Git Tag

$ git tag -a 0.0.1 -m "First release."

$ git push origin 0.0.1

将包发布到注册表

既然我们已经为我们的包选择了一个合适的名称,并分配了一个版本号(以及 GitHub 上相应的标签),现在是时候将我们的包发布到公共的 Bower registry 了:

$ bower register``my``-``package``-namehttps://github.com/username/``my``-``package``-name.git

Note

请记住,Bower 旨在作为其他开发人员可以在自己的项目中使用的库和组件的集中注册中心。它并不打算作为整个应用的分发机制。

摘要

Bower 是一个简单的命令行工具,它简化了一些与管理前端素材相关的繁琐任务。与来自其他平台的众所周知的包管理器(例如 Node 的 npm)不同,Bower 不是为处理任何一个平台或语言的特定需求而设计的;相反,它倾向于用一种相当通用的方法来处理包管理的概念。创建 Bower 的开发人员有意创建一个非常简单的工具来管理各种各样的前端素材——不仅仅是代码,还有样式表、字体、图像和其他不可预见的未来依赖。

开发外部依赖性很小的普通 web 应用的开发人员可能会发现 Bower 带来的好处没有什么价值。也就是说,琐碎的 web 应用有迅速演变成复杂的 web 应用的趋势,随着这一过程的发生,开发人员通常会逐渐意识到 Bower 的好处。

无论您认为您的项目有多复杂(或多简单),我们都鼓励您尽早考虑将 Bower 集成到您的工作流程中。痛苦的经历告诉我们——项目本身。犯了结构过小的错误,你就有可能造成不断增加的“技术债务”负担,最终你必须为此付出代价。在这些不受欢迎的选择之间取得微妙平衡的过程既是一门科学,也是一门艺术。这也是一个从未完全学会的过程,但必须随着我们的贸易工具的变化而不断调整。