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