Web前端自动化构建:Gulp、Bower和Yeoman开发指南(txt+pdf+epub+mobi电子书下载)


发布时间:2020-07-02 12:52:27

点击下载

作者:(奥)斯特凡·鲍姆加特纳(Stefan Baumgartner)

出版社:机械工业出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

Web前端自动化构建:Gulp、Bower和Yeoman开发指南

Web前端自动化构建:Gulp、Bower和Yeoman开发指南试读:

前言

本书重点关注的是广义的开发工作流,涵盖了开发者开发和维护项目时将会面临的三个阶段,分别是初始化、开发和部署。对于每个阶段,本书都详细解释了这一阶段的需求和概念,并且介绍了一个合适的工具来实现这些需求。

在现代Web开发中,新的工具层出不穷,但是寿命往往都很短。我写本书花了超过一年的时间,这在JavaScript界可能相当于过了十年。工具日新月异的变化对写书提出了巨大的挑战,但同时也提醒了我不要过于关注工具本身。因此,本书介绍的每个技术都可以轻松地替换为另一种合适的工具,而不会影响关键的概念。另一方面,本书挑选工具的标准不是工具的流行程度,而是工具的可维护性(sustainability)。本书介绍的工具都被广泛使用,且具有一定的用户基础和宽广的应用空间。正是因为这些特点,本书在几年后依然会有参考价值。目标读者

本书的目标读者是想要在日常工作流中添加自动化流程和工具链的开发者。本书建立的工作流模板既适合初学者,也适合有经验的开发者。尽管市面上已经有了许多教程和博文来介绍这些工具,但大都只是单独介绍其中的某一个。而本书则把所有这些工具融合到一个工作流中,绝不仅仅只是介绍工具用法这些表面知识而已。本书大纲

本书分为两部分,每一部分包括五章。

第一部分介绍一套全新前端开发工作流和相关的工具,不仅描述了如何用三个专门的工具来搭建一个工作流,还介绍了前端开发工作流的一些总体构想。建议按照顺序来读这一部分。

·第1章展现了前端开发者日常面临的挑战,并且介绍了如何用三种类型的工具建立工作流以克服这些挑战。

·第2章介绍了第一种工具,也就是构建工具。它提供了抽象接口来自动化处理底层代码的任务(task)。这一章的内容主要基于Gulp。

·第3章介绍依赖(dependency)和执行链(execution chain)。这一章会结合上一章的任务,把它们添加到一系列的执行中,以此来建立一个本地的开发环境。

·第4章引入依赖管理的概念。这一章会介绍对于前端开发而言,扁平依赖树和嵌套依赖树之间的区别和优劣。这一章选择Bower作为依赖管理的工具。

·第5章是前端工作流的最后一步。这一章会介绍如何通过脚手架工具Yeoman,来复用第2章到第4章中搭建好的流程。

读完第一部分,读者就能够运用上述的三种工具来改进工作流,以适应自己的需求了。所有介绍的工具都使用Node.js作为运行时。刚刚接触Node.js的开发者可以参考附录来大致了解一下。

第一部分中介绍的Gulp、Bower和Yeoman都可以轻松地替换为其他工具。不过,第二部分就会深入探讨这三个工具的内在工作原理。其中每一章都可以提高工作流的效率,还会说明这些工具的独特和有用之处。

·第6章会介绍如何利用Gulp的特性,包括增量编译(incremental build)和管道开关(pipeline switch),来改变Gulp在不同开发环境中的输出结果。

·第7章深入解释了Gulp的底层技术——文件对象流(file object stream)。使用这一技术可以在不同的输入/输出场景中复用相似的管道。

·第8章介绍了Gulp的插件生态系统,并且告诉读者在选择新插件作为构建管道(build pineline)时,如何避免冗余的或者质量不好的插件。此外还介绍了如何通过Gulp的task和streaming API来集成插件以外的工具。

·第9章又回过来讲依赖管理。这一章介绍了模块(module)的概念,并且展示几个不同的模块规范之间的差异,模块能让我们更轻松地把依赖集成到应用中。

·第10章以脚手架工具(scaffolding tool)Yeoman来结束全书。在Yeoman sub-generator的帮助下,项目的脚手架不仅在项目初期十分有用,并且会贯穿整个项目的始终。

第二部分的目的是让读者精通这些工具。尽管这些工具的示例都是有联系的,但读者也可以跳着阅读分别来了解它们的概念和细节。代码格式和下载

本书包含了很多示例的源代码,有时会加粗代码,来凸显和前几章代码的不同之处,比如向代码中加入新功能。

大多数情况下,原始的源代码都被格式化过。本书在代码中加入了换行和缩进来适应本书的版面。在极端情况下,偶尔还会使用续行符(line-continuation marker)。另外,当源代码在正文中出现时,会移除源代码中的注释。包含重要概念的代码会附上注释。

本书中示例的源代码可以在出版社的网站www.manning.com/books/front-end-tooling-with-gulp-bower-and-yeoman上下载。

本书中的示例也可以从GitHub网站https://github.com/frontend-tooling上下载。项目“sample-project-gulp”中的分支中包含了每一章的解决方案。网上资源

·StackOverflow上的Gulp.js标签(http://stackoverflow.com/questions/tagged/gulp)里有很多问题和回答。上面的网友都非常友好而且见多识广,能够很好地回答一些特殊的问题。

·Yeoman网站(http://yeoman.io)不仅包含Yeoman自己的资源,也提供了关于其他工具的丰富的教程资源。

·作者的博客上也有很多Gulp和Yeoman的教程:https://fettblog.eu。这些文章更加简明扼要,解决的都是更为具体的问题。致谢

你可能觉得写书是一项孤独的工作,但事实却并非如此。

在所有帮助过我的人中,首先要提到的就是Lesley Trites。作为我在Manning的策划编辑,她给了我非常有价值的反馈,是我写作时最棒的伙伴。她手把手地教我写作的技巧,如果没有她,本书根本不会像现在这个样子。

说到Manning的编辑们,我跟技术编辑Johan Pretorious和Nick Watts也合作得非常愉快!感谢你们检查我提出的想法。

还要感谢那些在我的写作过程中提出了很多有用反馈的读者们,他们是:Andy Knight、David DiMaria、Giancarlo Massari、Harinath Mallepally、Jason Gretz、Jeroen Benckhuijsen、Johan Pretorius、Mario Ruiz、Nikander和Margriet Bruggeman、Palak Mathur、Tanya Wilke、Unnikrishnan Kumar和Zorodzayi Mukuya。

Alexander Zaytsev、Lars Johansen和Jens Klinger,他们怀着对开源的高涨热情,在我写书的时候,一直都在改进我在GitHub上的Gulp示例。

我所有关于前端工作流的知识都是Addy Osmani教我的。我从Sebastian Gierlinger和Blaine Bublitz那里知道了什么是开源。

Thomas Pink和Thomas Heller不仅是我最棒的同事,而且还一直提出有价值的问题,让我改进构建工具技术。他们对技术改进的推动和现实工作的具体需求是本书内容来源的坚实基础。

还要感谢“Working Draft”podcast上的热心朋友,他们是Christian Schaefer、Peter Kröner、Rodney Rehm、Anselm Hannemann和Hans-Christian Reinl,他们欢乐和富有挑战性的讨论让我不放过文中的每一个细节。同时还要感谢“Klassenfahrt”团队:Fabian Beiner、Sven Wolfermann、Sebastian Golasch、Der Pepo、Robert Weber、Marc Hinse、Bianca Kastl、Joschi Kuphal、Marc Thiele、Khalil Lechelt、Frederic Hemberger、Tobias Baldauf、Tom Arnold和Maik Wagner。没有你们我绝不会取得今天的成就。

人们总是对作家有一种浪漫的幻想,觉得他们每周都在法国普罗旺斯的小木屋中写作。为了满足读者的幻想,我要感谢我的岳父岳母Hans和Marianne,因为每隔一周的周末我都是在他们奥地利Innviertel的家中度过的。我还要感谢我的父母Hans和Rosi平时对我的照顾!感谢你们的支持!

最后,我最想感谢的人是我最爱的妻子Doris,她的耐心、爱意和关心对我来说无可替代。Doris,我欠你太多了。关于原书封面插图

本书封面插图的标题为“穿着中世纪衣服的男人”。这幅插图的作者是Paolo Mercuri(1804—1884),选自“Costumes Historiques”。这是一本多卷历史服饰简史,时间横跨12世纪到15世纪,由Camille Bonnard整理和编辑,并于19世纪50年代或60年代在巴黎出版。19世纪的人们对异国情调的兴趣日益增加,人们沉迷于这类收藏,因为这可以帮助他们探索所生活的世界和很久以前的世界。

Mercuri的这部历史藏书中丰富多彩的插图生动地展示了几百年前世界各地的城市和地区的文化差异。在街头或农村,仅仅通过服装,就可以识别出人们的生活状态、贸易和职业。几个世纪以来,着装习俗发生了变化。曾经的各个地区的服装的多样性,现在都已经渐渐消失了。如今我们已经很难区别来自不同大陆的居民,更不要说区别他们来自的城市和国家,以及社会地位和职业了。也许如今文化多样性已经被更为多样的个人生活所取代——一种更加多样、节奏更快的科技生活。

在这样一个计算机书籍逐渐趋同的时代,Manning利用几个世纪之前不同地域丰富多样的生活来制作图书封面,借此赞美计算机行业的创造力和引领时代的精神。第一部分 现代Web应用工作流

·第1章 现代前端工作流的工具链

·第2章 Gulp入门

·第3章 用Gulp配置本地开发环境

·第4章 Bower依赖管理

·第5章 脚手架工具Yeoman

第一部分介绍的是前端开发的工作流和工具链。这一部分中,读者将会了解前端开发者在日常工作中所要面对的挑战,并且将会学习如何通过三个工具实现一个工作流来克服这些挑战。

第1章介绍一套本书所推荐的工作流,以及用于管理这套工作流的工具。

第2章介绍第一个工具:构建工具Gulp。借助Gulp,你可以搭建一个测试和编译JavaScript和CSS文件的自动化流程。

第3章在第2章的基础上,把第2章的任务组织成执行链的形式。除此以外,还会搭建一个实时加载的开发服务器,它能够把构建的文件更新到本地开发环境中。

第4章介绍第二个工具:依赖管理工具Bower。在这一章中,读者将学习组件和依赖树方面的知识,以及如何使用Bower来管理第三方软件。

第5章会结合前几章的任务,通过脚手架工具Yeoman把这些任务进行打包。借助Yeoman,你可以打包出能够立刻开始开发的项目模板,以备将来使用。第1章 现代前端工作流的工具链

本章包括:

·前端开发所面对的单调重复的工作。

·脚手架和模板代码。

·依赖管理工具。

·构建工具。

·前端开发的工具链和工作流。

前端开发者们赶上了一个好时代。如今,浏览器的功能比以往更强大。新技术HTML5的到来给前端带来了无限可能。JavaScript再也不是一个玩具语言了,它能够开发各种各样的应用。越来越多的人采[1]用胖客户端(fat client)的应用架构,并认为它是一个优秀的开发Web应用的架构。

随着越来越多人重视JavaScript,为了给应用写出更好的代码,开发者也面临着不少挑战:运行代码编译工具(authoring tool)、打包文件、压缩应用大小、优化图片……开发者需要合适的工具,才能满足这些需求。

这一章会考察一些编程以外、但在日常工作流中开发者又无法避免的任务,并且说明工具对处理这些任务有何帮助。我们把这些任务分成三类,然后用三种工具来解决它们:

·构建系统,比如Gulp。只需要按一下按钮,它就能处理大量文件的更改。

·依赖管理,比如Bower。它能管理常用的类库的版本信息,提醒开发者类库之间的冲突,甚至有时候自己就能把冲突解决了。

·脚手架工具,比如Yeoman。它能提供一个项目运行所需的基本文件。只需要在控制台输入一行命令,就能用Yeoman创建一个全新的应用或模块。

这三个工具代表了前端工具链的基本理念:通过一系列必需的工具,来启动、运行和部署应用。在本书中,读者不仅会学到如何为自己和同事来配置这些工具,而且还会深入到每个工具中去,从而学会如何结合这些工具量身打造一个工作流,以满足自己的需求。[1] 胖客户端是在浏览器中直接运行应用的主要代码的应用架构。1.1 软件开发者的工作流和任务清单

下面是一个典型的软件开发工作流,从中可以清楚地看到开发者编程时会经历的三个阶段(见图1-1)。图1-1 开发工作流的三个阶段

·初始化:在任何软件开发过程中,初始化都是第一步。这一阶段的任务是搭建项目或者向已有项目中添加新文件。

·开发:这一阶段是写代码的阶段。如果需要加载更多模块或者想把一些代码重构成一个新文件,那就得回到初始化阶段。如果一切都没问题,就能前进到下一阶段。

·部署:到了这一阶段,代码已经写好了。这时就要创建可执行文件并且部署了。对于Web开发而言,就是部署HTML、JavaScript和CSS到Web服务器。在这一阶段,开发者可以回到开发阶段(修复bug或者添加新功能),也可以回到初始化阶段(创建新模块)。

虽然所有软件开发流程都有上面这三个阶段,但是不同技术领域的开发者实现这些阶段中的任务的方法却是不同的。尽管其中有些任务非常单调乏味,而且和编程没有直接关系,但是却很大程度上影响了安装、架构和优化。图1-2展示了JavaScript项目中典型的任务。图1-2 每个阶段的任务

初始化阶段的任务包括创建目录结构和应用模板代码,可能还会有下载和添加第三方库。开发阶段涉及一些代码编译工具,比如预处理器(LESS)或者JavaScript编译工具。大部分任务都是在开发阶段完成的。

图1-2展现了大量任务,接下来的章节会深入探究它们。读者接下来会面临很多任务,但是不要惊慌,本书的目的就是找到一个愉快而简单的自动化方案来解决它们。为了明白下一步要干什么,让我们逐个地来审视这些任务。1.1.1 初始化阶段的任务

初始化阶段的任务不是JavaScript专属的,而是各种编程语言都适用的。一开始,你得创建目录结构和第一个文件,然后才能开始编程。

1.建立一个熟悉且可靠的目录结构

基于以前的项目经验,你应该知道怎么组织代码和文件。开发者往往会在接下来的项目中继续沿用之前的项目结构,或许还有些许改进。如果你很熟悉目录和文件的组织方式,那么你就能快速开展新项目。

2.复用模板代码

模板代码(boilerplate code)是几乎不加修改就可以添加到项目中的代码。作为开发者,你要做的就是填空。模板代码不仅能够节约写代码的时间,还能确保那些常用的代码都能正确地引入到项目里。有了模板代码,就不用一切从头开始,从而能快速开发新项目。

3.安装第三方软件和库

像jQuery这样的库能提供一些基本功能和一个良好的开发基础。大家把这些库叫作“依赖”,意思就是一个应用能否成功运行就依赖于这些库了。1.1.2 开发阶段的任务

到了开发阶段,任务就转向了前端和JavaScript开发。

1.使用代码编译工具

近几年前端开发有一股热潮,就是使用各种代码编译工具。现在很多人写前端都不直接用原生的Web语言(JavaScript、CSS、HTML)来写,而是用其他语言来写。因为这样就能使用一些原生语言不支持的语法和特性,从而能写出更复杂的代码。但是浏览器不能直接解释这些语言,所以需要把代码编译成浏览器可理解、可运行的代码。开发阶段和部署阶段都会用到代码编译工具。

2.代码质量管理

开发者所写的代码应该是高质量的代码。它们应该易读、易懂、[1]不复杂,而且没有“代码异味”(code smell)。你可以按照代码规范或者使用代码风格检查工具(code style checker)来帮助你写出高质量的代码。像JSLint和JSCS这些工具都能根据一系列可配置的规则来检查开发者是否写出了不合规范的代码,并且还能提出警告。开发阶段和部署阶段都包括代码质量管理的任务。

3.运行开发服务器

Web应用运行在Web服务器上才能取得最好的效果。如果一个应用需要调用后端接口,并通过AJAX获取数据,那么在编程时运行一个模拟生产环境的开发服务器就很重要了。

开发阶段的任务迭代(iteration)必须能快速完成,这样才能马上看到代码修改的结果,而不用浪费很多时间。保存源代码文件时,应该会自动触发相应的代码编译工具,并进行代码质量检查,最后把运行结果展现在浏览器里。1.1.3 部署阶段的任务

正如图1-2所示,部署阶段包含的任务最多,因为大家都希望自己部署的应用能完美运行。除了开发阶段的两个任务以外,你还得做以下几件事。

1.打包和压缩JavaScript和CSS文件

你在HTML中引用的每一个文件都会导致浏览器建立一个新的HTTP连接去下载它。而在传输数据之前,每一个连接都需要一定时间才能建立完成。所以在部署代码时,最好把所有文件都打包成一个文件,这样就能减少对服务器的请求数。HTML、CSS和JavaScript基本上就是纯文本。相比于其他编程语言,它们不需要被编译成二进制文件。由于每一个字母在传输时都会产生一个字节的流量,所以需要用某些方式优化代码体积,比如说移除空格、缩短函数和变量名,或者本书提到的一些优化技巧。像UglifyJS和MinifyCSS这些工具也能帮助做这些事。

2.移除没有用到的代码

在开发中,开发者往往会在应用中添加一些多余的调试代码。结果最后这些代码在哪里都没被引用到,却白白占用了生产环境的流量。用户永远不会感觉到这些代码的存在,所以最好删掉它们。

3.优化图片

图片在一个网页的体积中占据了相当大的部分。由于图片格式的缘故,图片文件本身储存了很多元信息。这些信息不但无法被浏览器解释,反而白白占据了图片的体积。像ImageOptim和ImageMagick这些工具就能处理并删除这些元信息。它们还使用了优化过的压缩算法,能够分别减少JPEG和PNG图片将近10%和40%的体积。

4.执行单元测试和验收测试

单元测试确保模块的功能可以正常运行,而验收测试检查软件的输出结果能否满足特定需求。这两个测试可以保证应用在一般情况下不会崩溃。只有通过了这两个测试,应用才能被部署。

5.上传应用

最后,开发者要把文件部署到Web服务器上,并确保外网能够访问服务器。

如你所见,你有一大堆任务要做。除了要牢记这些任务以外,你还要处理一个可能会导致问题的额外情况,即人为因素。1.1.4 人为因素

很多任务都可以借助正确的工具来完成。比如用代码编译工具就可以编译代码,在命令行里输几个命令就能测试代码质量。但问题是,开发者不仅要知道这些工具,还必须知道如何使用它们。

这个过程会很单调,而且非常容易出问题。你可能会忘了执行某个任务,又有可能在运行命令时漏了一个参数。特别是在团队协作时,问题会更加复杂。比如说,你怎么才能确保同事在写完代码后没有忘记压缩代码呢?

流程越复杂,就越有可能出问题。设想这样一个情况:你要在不同的阶段运行十个工具,还要把每个工具产生的结果传递给下一个工具,你很容易就会搞不清现在进行到哪一步了。事实上,你希望运行一个简单的命令deploy就能做到这些事。而且最好不仅是你自己,连你的同事,甚至机器都能运行这条命令。

再仔细想想,如果你希望在部署阶段通过一条deploy命令就能执行所有的任务,那为什么不干脆通过一条init命令来初始化应用呢?又或者是用一条develop命令来运行所有开发阶段的任务?之后你就会发现,你的愿望其实很容易实现。[1] 指那些语法和功能上没有问题,但是风格非常糟糕,而且以后可能导致问题的代码。1.2 JavaScript工具和新的工作流

为了预防潜在的错误,开发者要尽量减少可能出错的地方。回顾你在项目中做的编程以外的任务,你会发现这些任务都只不过是在不同阶段处理代码而已。让我们回过头来看工作流的示意图,但这次我们关注的不是各个阶段本身,而是在这些阶段中代码发生了什么变化。如图1-3所示,图片的边框发生了一些变化。图1-3 根据任务对代码进行分类

最后会产生三类代码:套用代码(模板代码)、依赖代码(库、依赖)和预处理代码(自己写的JavaScript、CSS、HTML)。这三种类型的代码分别对应三种工具:脚手架工具、依赖管理工具和构建工具。让我们仔细研究一下这三类代码。1.2.1 三类代码及其工具

如图1-3所示,根据每个任务所要处理的代码的类型,可以把任务分成三类。结果你会发现,对于每一类代码,都能找到一个特定类型的工具来处理。

1.脚手架工具:模板代码

典型的模板代码的默认配置和结构都十分优秀,开发者只需要往里面填空就行了。模板代码也有很多种。有的模板代码只有简单的模块定义功能,有的模板代码几乎就是一个完整的程序,只需要加上必需的参数就能完成了。模板代码经常会被复制到新项目中,区别只是每次传入的参数不同,这样模板代码就能创建必要文件让开发者能插入自己的代码。

脚手架工具专门用来处理模板代码。它能初始化模板代码,并且快速启动应用。它还能创建目录结构,并且往现有项目里加入新模块,也就是说它能完成两个初始化阶段的任务。另外,脚手架工具还能为安装构建工具和依赖管理工具打下必要的基础。

2.依赖管理工具:依赖代码

依赖代码说白了就是类库。它要么是你自己之前写的作为独立组件被使用的代码,要么是第三方库的代码,比如jQuery。最重要的一点是,你在写程序的时候不会动这些代码。你仅仅只是使用它们,而不会修改它们。

依赖管理工具用来处理独立的库或者包。使用者不会触及其内部逻辑,而只是把它们添加到自己的项目里。依赖管理工具还会处理包之间的依赖。如果开发者想要安装一个模块,但是这个模块却不满足现有模块的需求(比如说一个轮播图组件需要一个新版本的jQuery),那么依赖管理工具就会自动更新旧的依赖,或者至少提示开发者有依赖需要更新。

3.构建工具:预处理代码

预处理代码是开发者自己写的需要处理或转换的代码。这部分代码一般是开发者耗时最多的代码,因为正是这部分代码实现了应用的各种量身打造的功能。你可能常常听说这句话:“你写的代码不是你部署的代码。”因为开发者往往会使用LESS这样的处理语言,并且打包JavaScript代码。另外,开发者还得注意代码风格并执行代码检查工具(lingting tool)。当你准备好部署代码时,还要压缩图片到最小体积,删除所有不需要的调试代码,删除没有用的CSS,并且尽量减少文件数量。最后才能把所有的文件通过FTP上传到服务器或者CDN。

构建工具专门用来应对所有的文件处理任务,把源代码转换成可以部署的代码。检查代码、编译、打包,这些任务构建工具也都能够处理。构建工具的配置一般保存在构建配置文件(build file)里,这些文件很容易修改和扩展。

除此以外,构建工具还能把已安装的依赖添加到现存的项目中。相比于用一大堆工具来处理开发阶段的任务,开发者更倾向于用下面三个工具来自动执行任务:脚手架工具、依赖管理工具和构建工具。图1-4展示了这三个工具是如何交互的。图1-4 三个工具在项目中的作用

开发者要做的就是控制这三个工具。首先,用脚手架工具(Yeoman)搭建项目,然后用依赖管理工具(Bower)来搜索、安装依赖,接着用构建工具(Gulp)来处理文件。图1-4还展示了这些工具的联系。Yeoman作为一个脚手架工具,可以初始化Gulp(构建配置文件)和Bower(项目基本的依赖)。Gulp还可以使用Bower所提供的信息把依赖添加到项目的主要文件中。

项目本身是这三个工具的核心。开发者通过工具的接口把工具整合到项目中。开发者通过脚手架工具来创建新应用的基础架构,通过依赖管理工具搜索和添加依赖,通过构建工具运行一条命令把源代码和前两个工具创建的代码集成到项目里。这样依赖就能用三个简单的接口来封装这些复杂的任务,让工具来处理最复杂的工作。迄今为止,很多运行时和运行环境都提供了这些工具。不过随着Node.js的出现,开发者有了一个更适合JavaScript的新环境。1.2.2 Node.js中的JavaScript工具

因为现在这三种工具每一种都有很多选择,所以决定使用哪一种工具的责任就落到了开发者头上。以前,尽管所有处理任务的工具都是用JavaScript写的(也有些著名工具是用Ruby写的),但是集成工具却都是用和JavaScript完全无关的语言写的。但是近几年发生了一些变化,一个专为JavaScript开发者设计的编程平台出现了:Node.js。

根据Node.js官网的描述,Node.js把Chrome的JavaScript引擎带到了一个适合开发快速网络应用的平台。但是Node.js之所以如此流行的原因却不在于此,而在于:JavaScript——这个以前被开发者用来开发浏览器应用的语言,如今可以摆脱浏览器的束缚了。

Node.js给开发者带来了和在Chrome中开发相同的体验,因为它们所使用的JavaScript引擎是一样的。但是JavaScript引擎只是Node.js的核心,图1-5展示了Node.js在JavaScript引擎之上的架构是怎样的。它的基础是V8引擎——Google Chrome的JavaScript引擎。Node.js的作者提供了核心的功能,使开发者能够接触操作系统,最上面的一层是程序和模块(封装好的可复用的程序)。

让我们逐一解释这些部分:

·V8运行时是Google Chrome的JavaScript引擎。它提供了编译和运行JavaScript的环境,但是不包含浏览器的API。

·Node.js核心由和操作系统相关的API组成,包括文件系统、网络协议和流,简而言之就是所有涉及I/O和操作系统的功能。

·程序是可以在Node.js中运行的JavaScript代码。

·模块是Node.js中的一个概念,用来保证代码的复用性。所有的程序都可以被打包成一个模块,并且作为一个包发布。模块提供了封装好的功能,开发者可以在新程序中复用它们。图1-5 Node.js生态系统的组成部分

对工具而言,Node.js最重要的一点是Node.js核心层。因为Node.js提供了操作系统相关的功能,其中大部分是关于文件系统的。有了操作文件系统和修改文件的能力,Node.js就成为了一个用来编写构建工具的完美环境。

Node.js有一点和其他开发环境(比如Java、Ruby)完全不同:开发者不需要任何心理负担就能从前端开发转向工具开发。因为这两者用的都是同一个语言,运行环境也是一样的。JavaScript开发者可以轻松地开发自己的工具用来转换JavaScript代码。

尽管还有很多替代的工具,我们还是主要关注JavaScript界最流行的三个工具,分别是:Yeoman,由Google开发,作为脚手架工具;Bower,由Twitter开发,作为依赖管理工具;Gulp,作为构建工具。注意 之后所有在命令行中运行的示例代码都是根据Unix bash语法而写的。但这并不意味着这些代码只能在Unix系统中运行。Unix/Linux bash、Mac OS X终端和Windows的命令提示符都能以同样的方式运行这些代码。1.3 用Yeoman搭建脚手架

脚手架工具的作用是搭建项目,让项目顺利跑起来。脚手架工具可以创建一个项目必需的目录,并且把初始文件(比如构建代码)、模板代码复制进去,最后安装依赖。在整个开发过程中,脚手架工具的定位是创建项目的基础架构。但是它做的事情又不仅仅是把文件从一个地方复制到另一个地方。它还可以根据用户输入的参数而修改文件。参数可以是项目或者模块的名称,也可以控制是否要引入某个模块(比如jQuery)。详情见图1-6。图1-6 Yeoman会从generator接受定义好的模板,然后根据用户输入的参数,对模板进行一些修改。修改好的模板可以被添加到现有项目中,也可以用来创建一个全新项目1.3.1 Yeoman作为脚手架工具的优点

搭建脚手架可以通过机器完成,而且通常它是IDE的一个功能。在像Eclipse、WebStorm和IntelliJ这类工具中,你可以用模板创建一个新项目,或者创建一个新模块。通常还会有一个向导来向你询问一些搭建脚手架所必需的参数。

如果你选择用IDE来搭建脚手架,你就得在开发过程中一直用它,间接导致你的同事也不得不使用它。这种时候,像Yeoman这样的独立脚手架工具就有巨大的优势:它的功能很单一,就是启动一个项目和模块,和其他开发环境并不耦合。因此,无论你的环境或者工具链怎么改变,都可以使用Yeoman来启动新项目。即使你在项目开发到一半时放弃Yeoman,也不会给你的项目带来什么问题。而且Yeoman可以像很多其他Node.js工具一样在命令行运行,这和Bower和Gulp是一样的。

但是Yeoman最大的好处在于它所使用的名为generator的插件系统。1.3.2 什么是generator

generator是可以被命令行工具yo执行的JavaScript应用,它所做的事情只不过是创建新目录和复制文件。不过,它也没有那么简单。它还可以监听参数来修改文件。generator一般由一个目录构成,目录中是模板文件,这些模板会被generator的代码所修改。

Yeoman的唯一任务就是运行generator。generator知道应该把文件复制到哪里。generator有一个简单的安装提示的API,从而可以接受用户输入的参数并更改输出的结果。Yeoman团队制作了一些generator,包括:Web应用的generator,还有Ember和Angular的generator。Angular的generator很受关注,因为它也是Google开发的。

Yeoman用起来很简单。你安装完一个generator以后,就可以在命令行里用yo命令来调用它。你可以直接通过yo generator-name命令来执行一个generator。下面以Angular generator为例。打开命令行(或者终端),然后进入到你想创建新项目的目录。执行yo angular命令来让Yeoman启动Angular generator。你会看到一些安装提示,需要你回答问题:

在shell或者命令行中执行这个命令来启动Yeoman。这个命令由yo和generator的名字组成。根据你的回答,generator会决定是否引入相应的代码。其中有一个多选题,里面有一些预先选好的推荐模块。你也可以用空格来取消它们。

通过Yeoman你很快就可以启动一个新项目。就比如说这个Angular项目,它已经被很多开发者检验过,成为了社区里的标准,你完全可以相信它。这样你就不用把时间浪费在目录、文件结构、名称这些细节上,可以更加专注于开发。

下面让我们看看依赖管理工具。1.4 依赖管理工具Bower

依赖是独立完整的模块,它是一个应用的一部分或者扩展。依赖可以是像jQuery或Angular这样的库,可以是一些UI组件,也可以是像Bootstrap这样完整的UI框架。依赖的另一种叫法是包(package)。使用依赖或者包的好处在于:你不用花时间去开发那些已经有的功能,只要用现成的就行了。

依赖管理工具的主要功能是在社区和公司的仓库中搜索依赖,并且下载到本地的项目中。由于包也可以拥有依赖,因此依赖管理工具的任务绝不仅仅只是把文件下载下来而已。如果有两个或以上的包都依赖jQuery,但是依赖的版本却不同,那么依赖管理工具此时就要解决这个冲突。解决方法可以是选择其中一个,也可以两个都安装,或者是让用户来决定选择哪一个。参看图1-7。图1-7 Bower作为包管理器能够在包的仓库中搜索依赖。如果发现版本不符合,它还会更新依赖。如果一些正常,这些依赖就会被下载下面并添加到项目里1.4.1 Bower的优点

Bower自称是为Web而生的包管理器,事实上也是这样。它是由Twitter开发的,专门用来从网上安装框架、库和其他模块。只要一个模块是由Git托管的,并且拥有bower.json文件,就可以用Bower来安装。

Bower是专门为前端开发者而设计的。但是这并不是说它只能引入JavaScript、CSS或者其他相关的语言。但是由于它是为前端而开发的,而且所有的包都需要在HTML引入才能使用,所以其他语言的开发者也不会用它。Bower提供了搜索、安装和更新包的命令。当你要安装一个包的时候,Bower会检查这个包需不需要其他的包(比如jQuery)。而且,它还会检查是否有哪个包重复安装了,或者版本冲突了。如果没有冲突的话,那么新的包就会被添加到项目中。

在众多包管理器中,我们选择了Bower。理由主要是下面几条:

·Bower是为前端开发者设计的。所有主流的前端库都能够使用这个工具。

·包的仓库(repository)的发展非常迅速。由于Bower专注于前端领域,所以包的数量都还可控,也不会遗漏哪个包。

·Bower的依赖树是扁平的。Bower的这一点不仅是独一无二的,而且对于Web开发者也是必要的。实践表明,扁平的依赖树的结构是最适合Web应用的,因为你不会(至少你不需要)安装两个同样的包。1.4.2 Bower的依赖树

依赖树是用来展示依赖之间的关系的。以Bootstrap为例,它需要jQuery才能运行。在依赖树中,jQuery是Bootstrap的一个子节点。如果你安装了另一个依赖jQuery的组件,你有两个选择:

·再次下载jQuery,然后把jQuery作为这个新的组件的子节点。

·把这个新组件引用的jQuery指向已经安装的jQuery。

图1-8展示了这两个选择。图1-8 这是两种依赖树:一个是深依赖树,它会重复安装依赖;另一个是扁平依赖树,每个依赖只会安装一次

这两个选择都有优缺点。深依赖树可以确保安装的依赖完美兼容组件,依赖的API就是组件需要的API。但是每次都重新安装依赖,会导致重复安装。另一个选择,扁平依赖树则可以确保每个依赖只会安装一次,整个项目里每个组件只有一个,但是这可能会导致依赖之间的版本冲突。

Bower使用了后者,理由是:在Web应用中,不应该把一个包重复传输好几次。如果你安装了jQuery,并且在整个项目中使用,那么浏览器就没办法在另一个地方再运行一个jQuery了。扁平依赖树更适合前端开发。如果安装依赖的时候出现了冲突,它会警告开发者,此时开发者可以采取下面这些选择:

·取消安装

·用新的依赖覆盖旧的

·仍然使用旧的依赖

有了Bower,你就可以用工具来管理所有的第三方模块和组件了。如果你选择第三个选项,就可以保证依赖和代码都可以正常工作。1.5 Gulp流式构建系统

构建系统是整个工具链的核心。它会处理所有的源文件,把它们变成可以部署的代码。它还可以检查代码质量,自动执行重复的操作。图1-9展示了构建工具是如何工作的。

构建工具首先会读取一个构建配置(或者构建文件),然后定义三个东西:源文件、处理流程和输出文件的目录。源代码经过处理的流程后,最后会被输出到目录中。在我们的工具链中,我们使用Gulp作为构建工具。1.5.1 Gulp的优点

Gulp不是第一个JavaScript构建工具。它的先驱Grunt比它争议更多,历史也更久。但是Gulp的构建方法和它完全不同,而且不仅仅在JavaScript界,在整个构建系统界都是独特的:

·Gulp底层的计算完全是在内存中运行的,而且读取数据非常快。这样就可以快速转换文件,灵活组合构建管道。如果构建管道里有一个工具不需要了,只要把调用它的那行代码去掉就行了,其他部分仍然能照常运行。图1-9 Gulp作为一个构建工具,可以调用其他工具来把源代码转换成可部署的文件,构建的命令都保存在构建文件中。Gulp工作的流程是:接受输入的文件,对它们执行不同的命令(或工具),然后把结果保存在新目录中

·Gulp可以并行执行任务。开发者可以指定哪些任务按顺序运行,哪些同时运行。比起其他工具,这又是一个性能提升。

·Gulpfile是纯Node.js代码,开发者可以在Gulp的任务中执行任何兼容Node的JavaScript代码,这也是Gulp作者极力推崇的。比起使用Gulp插件,它更青睐直接使用Node.js模块。所以,很多Gulp开发者也尽量把他们的功能做得更通用,从而在Gulp以外的Node.js社区中也能使用。

·Gulp可以创造出非常高级的构建管道,甚至能超越其他一流的工具。1.5.2 构建管道

Gulp的主要目标是定义一个处理文件的管道,让源文件通过一个个的处理步骤。每个步骤都会修改文件内容,然后把结果传递给下一个步骤。这就是为什么Gulp自称是流式构建系统。Gulp插件是通过方法来调用的,你只要调用它,剩下的工作都由插件来完成。图1-10展示了这个过程。图1-10 基本的构建流程。首先把所有JavaScript文件合并成一个,然后用Uglify压缩,最后的结果保存在main.js文件中

实现的代码和流程也非常相似。因为用到了其他用Gulp封装的工具,所以你要首先加载其他必要的Gulp插件。

首先要加载Gulp。Uglify插件包括了原始的Uglify程序,它是用来压缩Java-Script代码的,同时也提供了很方便的API。要合并文件可以使用Concat插件。这个插件是Gulp作者写的,因为这个需求太普遍了。

然后要定义你要执行的task。下面的代码就是图1-10的实现。

整个处理过程都是在内存中进行的,只有在最后才会把结果写入硬盘中。这使得整个过程非常迅速。自从2013年Gulp发布以来,Gulp就一直受到对自动化和性能有着强烈需求的开发者们的追捧。

Gulp也是从命令行执行的。只要在bash或者shell中执行gulp scripts命令,Gulp就会执行定义好的scripts task。然后Gulp就会从Gulpfile读取构建指令,并且把它传给Node.js的运行时环境。

通过Gulp,你可以把多个文件处理工具整合在一起,并且非常方便地在命令行里调用它们。Gulp作为构建工具是本书第一个要介绍的工具。因为它的处理文件的功能是整个项目中所有流程的基础,所以下一章我们就会详细介绍它。1.6 总结

本章主要介绍了如何使用自动化工具来帮助前端开发者更好、更快地管理复杂的任务:

·前端开发者开发复杂的Web应用的时候,需要执行很多任务,其中包括繁重的文件转换任务,比如压缩和打包。所有这些任务都是和工具紧密联系在一起的。

·为了降低复杂度,我们主要采用了三个工具:创建代码的脚手架工具、下载和安装代码的依赖管理工具,以及处理代码的构建工具。

·这三个工具定义了一个新的工作流:用脚手架工具创建应用,用依赖管理工具下载需要的依赖,然后使用构建工具来执行代码编译工具。

·这三个工具都有基于Node.js的版本。Yeoman是Google开发的脚手架工具。它特有的generator件可以根据不同的设置来搭建脚手架。

·Bower作为依赖管理工具可以检查模块和组件的版本,并它们集成到项目中。它采用了扁平依赖树,可以避免重复的依赖,这一点对Web应用非常合适。

·构建工具Gulp有非常方便的命令行接口,还有众多插件可供使用。只需要几行代码,就能用链式操作把文件转换步骤连接起来。

Gulp是整个项目的核心,也是最主要的工具。第2章你就会开始学习使用Gulp。第2章 Gulp入门

本章包括:

·Gulp的介绍。

·流的概念。

·给自动化工具创造简单任务。

·为多功能任务创建执行管道。

创建新工作流时,最重要的是构建系统。虽然构建系统在上一章是放在最后介绍的,但是它却是整个工作流必要的基础。构建系统的作用是处理日常工作流产生的任务,比如合并、压缩和测试代码。构建工具是由脚手架工具来初始化的,然后构建工具会把依赖管理工具集成到项目中。图2-1展示了构建工具在整个工作流中的定位。

Gulp是实现自动化工作流的基础,它是脚手架工具最先初始化的元素,之后构建工具再把其他组件集成到项目中。而且,由于构建工具能创建开发环境,所以它在整个开发周期中也是最常用的工具之一。

Gulp是用JavaScript编写、运行在Node.js上的构建工具。因为Gulp是一个Java-Script程序,而且它的指令也是用JavaScript编写的,所以Gulp非常贴近JavaScript开发者的日常工作环境。因此,Gulp就成了前端开发者自动化处理日常任务的首选工具。这一章讲的是如何为项目配置Gulp,从中你会了解到Gulp配置的方方面面,并且学会如何编写构建指令来构建JavaScript和CSS。图2-1 第1章的工作流配置2.1 配置Gulp

作为一个Node.js工具,Gulp是由很多部分组成的。这一节会介绍Gulp的各种构建块以及如何安装Gulp的命令行接口和本地Gulp。2.1.1 Gulp的构建块

一般而言,构建工具由两部分组成:执行构建任务的工具和包含构建指令的配置文件。Gulp也不例外。Gulp执行构建任务的工具就是Gulp,而Gulp的构建配置文件叫作Gulpfile。Gulp还能被继续拆分成其他几个部分。图2-2展示了Gulp的各个部分以及它们之间的关系。项目示例和Node.js

本书提供了所有可能用到的项目示例,还准备了一个示例程序,读者可以在http://github.com/frontend-tooling/sample-project-gulp查看。如果你熟悉Git,那你可以使用clone命令来下载它们,否则可以点击网页上的Download Zip按钮来下载文件。

要使用这些示例,你必须要安装并且能在系统中运行Node.js。你可以在https://www.nodejs.org上找到兼容你的操作系统的Node.js安装包和安装方法。图2-2 Gulp CLI根据命令行中输入的参数启动本地Gulp。本地Gulp读取Gulpfile。Gulpfile加载Gulp插件,并且用Gulp API定义task。最后由本地Gulp来加载这些task

完整的Gulp安装流程包括以下几个部分:

·Gulp CLI:启动构建工具的命令行接口。

·本地Gulp:构建时实际运行的程序。

·Gulpfile:告诉Gulp如何构建软件的指令文件。

·Gulp插件:众多用来合并、修改、组装文件的插件。

要做的事情真多啊!但是不用担心,这一章就能把这些事全搞定。首先从CLI开始。2.1.2 Gulp命令行接口

Node.js模块可以全局安装,所以用户可以像使用命令行工具一样使用Node.js模块。Node.js模块也可以安装到本地目录,作为项目依赖的库使用。图2-3展示了这两种安装方式。图2-3 Node.js模块有两种安装方法。如果你全局安装一个模块,那么你就能在命令行里直接执行这个模块,用它来修改你想要修改的文件。换句话说,它就是一个工具。如果你本地安装一个插件,那么你就可以在别的程序里面调用这个模块的功能

Gulp也是如此,除了有一点不同,那就是Gulp有两个独立的包。一个是Gulp的命令行接口(以下简称Gulp CLI),它需要全局安装,所以Gulp能够在终端、bash和命令提示符中直接运行。另一个是本地的Gulp,它是真正的Gulp运行时。负责处理所有任务,并且提供所有的API。Gulp CLI是本地Gulp的全局的入口,它负责把所有参数转发到本地Gulp,还有显示项目里安装的本地Gulp的版本。后面的就都是本地Gulp的任务了,主要由它来处理构建。

Gulp CLI看起来有点傻,因为它的唯一作用就是检查能否运行本地Gulp。这么设计的原因是为了确保即使Gulp CLI和本地Gulp的版本不同,也能够运行Gulp。想象一下,你有一个项目用的Gulp是3.8版本的,而Gulp CLI仍然能运行这项目,原因就是本地Gulp的接口是一样的。即使是一个用了Gulp 4的新项目也能用同一个Gulp CLI运行。你会发现,无论本地Gulp是什么版本的,你都能用同一个Gulp CLI运行,而且甚至你可能还从来没更新过Gulp CLI。

要安装Gulp CLI,首先启动bash、终端或Windows的命令提示符(这些平台都支持),并且输入下面的命令,检查是否正确安装了Node.js:

如果已经安装了Node.js,这行命令就会输出当前Node.js的版本。下一步是检查Node.js的包管理器——NPM,它是随着Node.js一起安装的。运行下面的命令:

同样,这行命令的输出结果应该是NPM的版本。如果这两个程

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载