Yeoman按照官方说法,它不仅是一个工具,仍是一个工做流。它其实包括了三个部分yo、grunt、bower,分别用于项目的启动、文件操做、包管理。但我并不太认同这是一个工做流的说法,至少目前来看还不够成熟,在真实的生产环境中会遇到许多问题。而将来的可能性大体应该有两条路可走,也许会产生某些工做流的标准来定义前端开发的软件质量,不过我更认为Yeoman应该走向高可定制的工做流工具的方向,而不是自身做为一个工做流来存在。css
Yo是一个项目初始化工具,能够生成一套启动某类项目必须的项目文件。能够经过npm安装它到全局:html
npm install -g yo
而后还须要安装一些generator,这是一个用于建立某个指定类型项目的生成器。好比安装一个最经常使用的webapp的生成器,而后就能够在项目路径下生成项目启动须要的全部文件,像这样:前端
npm install -g generator-webapp cd /project_folder/ yo webapp
可是这种机制有一个很严重的问题,generator产生的文件结构是谁制定的?没有一个官方的相应的标准或者说Guide,generator的形式良莠不齐,甚至我发现Firefox OS的generator生成的是一个API接口的Demo而不是一个种子,若是要进行开发须要进行不少删减。node
不过产生这些generator的generator倒是一个很好的工具,它应该是一个创造性的工具。首先须要安装generator-generator,而后使用它,接着会看到字符拼接的yeoman,像这样:jquery
npm install -g yo generator-generator $ mkdir ~/dev/generator-blog && cd $_ $ yo generator _-----_ | | |--(o)--| .--------------------------. `---------´ | Welcome to Yeoman, | ( _´U`_ ) | ladies and gentlemen! | /___A___\ '__________________________' | ~ | __'.___.'__ ´ ` |° ´ Y `
固然使用它以前应该将写好的项目文件放入 app/templates
文件夹中,并在 templates
同级的路径中加入 index.js
进行配置就能够了。这里的index.js是运行在Nodejs中的,也就是说由它将templates中的项目文件放入该放的地方而且填入一些变量去构建整个项目。这里才是体现一个generator是不是一个好的generator的地方,若是仅仅是将一堆写好的项目文件下载下来那什么意义也没有,不存在万用种子。只有在使用generator生成项目时高度定制才是其意义所在,而相关标准才是最难的部分。git
Bower是一个相似于npm的包管理器,但不一样的是Bower主要针对前端,而且直接从Github查找须要的库下载到本地缓存。使用很简单,用npm安装bower后能够安装Github的项目并指定版本号,还能够重命名。默认会下载到项目中的 bower_components
文件夹中。github
npm install -g bower bower install jQuery bower install jQuery#1.10.3 bower install jQueryOld=jQuery#1.6.4
还能够经过bower.json文件来配置须要安装的包,使用 bower init
命令就能够生成bower.json文件,而后在其中写入须要的包及其版本便可web
{ "name": "my_project", "version": "0.1.0", "main": [js/js.js, css/css.css], "ignore": [ ".jshintrc", "**/*.txt" ], "dependencies": { "<name>": "<version>", "<name>": "<folder>", "<name>": "<package>" }, "devDependencies": { "<test-framework-name>": "<version>" } }
固然它也能够搜索包,像这样搜索一下jquery。shell
bower search jquery
若是以为bower_components的文件夹名太长很差,能够在 .bowerrc
中以json的形式修改它的路径npm
{ "directory": "lib" }
还有许多其余的配置,能够在Bower存放在Google Doc的文档中查看。
可是Bower还有一个Bug,jQuery在Github上的项目文件是分模块的,必须使用项目中的Grunt才能打包成jquery.js文件,而官方的说法是使用小写q的 jquery
来获取components项目中的jquery文件,可是目前Bower是大小写不分的,因此没法获取独立的jQuery文件。若是bower能够指定获取某个项目中的某个或某些指定的文件将会更加犀利。
甚至Bower能够在Nodejs中运行一个 bower.commands
文件来让你编写安装各类包的node程序,而且能够监听 end
事件在安装结束后进行操做,这是异步的,这样就能够为所欲为的安装包和控制顺序了。
var bower = require('bower'); bower.commands .install(['jquery'], { save: true }, { /* custom config */ }) .on('end', function (installed) { console.log(installed); });
Grunt目前来讲是这三个Yeoman中最成熟最强大的,最关键的是Grunt有各类各样的插件,能够集成大部分能想获得的开发工具来进行自动化开发。另外Grunt的做者还开发了一整套的插件来适应常规的开发,这套插件以 grunt-contrib-
为前缀(下文中如无特殊说明,均指带有该前缀的插件名),除了文件的基本操做,还包括有测试、编译、压缩、代码检查等各类功能的插件,并且不止一个选择。
安装Grunt和Bower不太同样,须要先在全局安装一个Grunt的客户端,而后在每一个项目中安装Grunt。
npm install -g grunt-cli cd /project/ npm install grunt
不过和Bower类似的是,能够经过编写配置json文件来使用 npm install
来安装Grunt和全部须要的插件,另外Grunt的插件也都是npm管理的,因此能够直接在 package.json
中直接编写。
{ "name": "myProject", "version": "0.1.0", "devDependencies": { "grunt": "*", // other plugin... "grunt-contrib-watch": "*" } }
安装完成后在项目根目录中创建 Gruntfile.js
文件来配置Grunt的工做流程。下面以 copy
插件为例使用Grunt进行开发。在 exports
中Grunt会以参数形式被传入函数,它有3个方法, initConfig
、 loadNpmTasks
、 registerTask
,分别用来定义插件操做,载入插件,注册任务。
module.exports = function (grunt) { grunt.initConfig({ copy: { main: { files: { src: ['path/**'], dest: 'dest/' } } } }); grunt.loadNpmTasks('grunt-contrib-copy'); grunt.registerTask('default', ['copy']); };
在配置中以插件名为键定义一个Object做为该插件的配置,其中还能够再定义一层以任务名为键,好比 main
,而后是插件的部分,copy插件使用 files
来定义对文件的具体操做, src
是要复制的文件, dest
则是要复制到的路径。
而后使用 loadNpmTasks
加载插件,须要写全名,包括grunt-contrib前缀。
最后是注册一个任务,这里的任务便是执行操做时须要调用的东西。好比代码中注册了 default
任务,包括一个数组中的全部任务,这样在执行default任务时就会执行相应的全部任务。另外default是一个特殊的任务名,若是在执行任务时没有指定名称,则执行该任务。固然直接运行copy任务也是能够的,甚至能够指定一个子任务,好比main。因此下面4行代码是相同的效果。
grunt grunt default grunt copy grunt copy:main
不过须要特别注意的是,注册的任务名不能和原有的任务相同,这样会报错,好比这样:
grunt.registerTask('copy', ['copy']);
和copy相似的文件基本操做还有 clean
清除, concat
链接, rename
重命名, compress
打包, crypt
编码等等,相关的配置能够在npmjs.org上的对应项目介绍中找到。
还有四个用于压缩的插件 htmlmin
, cssmin
, uglify
, imagemin
分别对应HTML文件、CSS文件、JS文件和图片文件;以及两个用于检查代码的插件 csslint
, jshint
分别检查CSS代码和JS代码。
固然,最重要的是,Grunt能够编译一些CSS和JS的其余形式代码。coffee
用于编译CoffeeScript,而CSS就更多了,好比SASS可使用 compass
或者 sass
, 还有 less
和 stylus
,我最喜欢的是Stylus,由于它使用的是Javascript来编译,而不像SASS是Ruby编译的,还须要准备Ruby的环境,很是麻烦。并且在Stylus中还能够写相似JS的条件语句和循环语句。这个国旗icon的项目很好的使用了Stylus以很短的代码完成了上百个国家的图标的CSS Sprite - National Flag on Github。还有许多种Javascript模板的预编译插件,haml
, jst
, jade
, hogan
等等。
除了用于编码的插件,还有许多用于测试的插件,在grunt-contrib中提供了三个测试框架的插件, nodeunit
用于Nodejs,qunit
用于Qunit,是来自jQuery团队的测试框架,还有Junit的后继者 jasmine
。另外Mocha也有本身的Grunt插件 grunt-mocha
。用于捕获多个浏览器测试框架karma也有相应的插件 grunt-karma
。
此外,contrib中还有一些其余插件,好比 connect
用于http等协议的请求,支持https, commands
用于执行shell命令, manifest
用于生成离线应用所需的 manifest.appcache
文件,还有用于插件YUI文档的 yuidoc
。
最最重要的一个插件就是 watch
,它能够随时监听某些指定的文件,当它们发生改变时执行相应的任务。再次使用copy作例子,添加watch任务后能够在原有文件发生改变时,将复制过去的副本也同步改变。
module.exports = function (grunt) { grunt.initConfig({ watch: { copy: { files: 'path/**', tasks: 'copy' } }, copy: { main: { files: { src: ['path/**'], dest: 'dest/' } } } }); grunt.loadNpmTasks('grunt-contrib-copy'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.registerTask('default', ['copy', 'watch']); };
由此,项目开发中的大部分工做都交由程序代替了人工,Yo和Bower能够快速的启动一个项目,Grunt在开发中能够自动化的持续完成编码中重复性的工做以及自动化检查和测试代码以提升质量。
个人前端开发工做流 系列文章:
原文博客http://www.tychio.net/tech/2013/09/25/improve-workflow.html