前幾天看了一篇文章大受啓發:我理想中的前端工做流,如今工做中一直在使用gulp和webpack作自動化,在單獨項目中效果很不錯。可是隨着項目逐漸怎多,是須要使用一個工具來幫你快速建立和規範項目。javascript
Yeoman是一個腳手架,能夠快速生成一個項目的骨架。官網上有不少你們已經寫好的腳手架,也能夠本身寫一個適合本身的,接下來我會翻譯下官網的教程,學習的同時把經驗分享給你們。css
Yeoman只是幫咱們生成項目的骨架是遠遠不夠的,官網上介紹,Yeoman是由三部分組成的:腳手架工具 - Yo、構建工具 - Grunt or Gulp、包管理工具 - Bower or npm。html
翻譯yeoman官網Creating a generator流程(一)Getting started 快速開始
(二)Running Context 生命週期
(三)User Interactions 和使用者互動
(四)composability 組合
(五)Managing Dependencies 依賴管理
(六)Interacting with the file system 文件操做前端
原文地址:http://yeoman.io/authoring/index.htmlvue
1.首先要創建一個文件夾,在這個文件夾內寫你的generator,這個文件夾的名字 必須 被命名爲generator-name
,name爲你generator的名字,假如我想寫一個vue的腳手架,我能夠命名爲:generator-vue
,這個很關鍵,Yeoman文件系統只會信任這種規範的generator。java
mkdir generator-vue
2.創建node模塊,首先要必備文件 package.json
,這個文件能夠經過執行 npm init
指令來生成,前提是須要安裝 node 及 npm。node
{ "name": "generator-vue", "version": "0.1.0", "description": "", "files": [ "app", "router" ], "keywords": ["yeoman-generator"], "dependencies": { "yeoman-generator": "^0.20.2" } }
幾點要求:webpack
1. name:必須格式爲 `generator-你項目的名字`。 2. keywords:數組中必須有 `yeoman-generator`,這樣你的項目纔會被[Yeoman官方的generators列表](http://yeoman.io/generators/)所收錄。 3. 若是須要添加其餘的屬性能夠去[npm官網文檔](https://docs.npmjs.com/files/package.json#files)中查看。
經過1.1步驟已經有了package.json,下一步在新建兩個文件夾分別叫app和router,結構以下。git
├───package.json ├───app/ │ └───index.js └───router/ └───index.js
當你執行Yeoman指令 yo vue
(上面你已經創建的項目名字)的時候,他會默認執行你根目錄下app/index.js的內容,因此一個新項目,app/
目錄是必須的。github
router/
做爲子項目,能夠經過 yo vue:router
來執行。
├───package.json └───generators/ ├───app/ │ └───index.js └───router/ └───index.js
若是不喜歡把全部項目都放在根目錄下,Yeoman還容許把項目放在 generators/
下面,改寫上面的例子:
├───package.json └───generators/ ├───app/ │ └───index.js └───router/ └───index.js
若是更改了文件目錄,要同步修改 package.json
中對應文件的目錄結構:
{ "files": [ "generators/app", "generators/router" ] }
module.exports = generators.Base.extend({ // The name `constructor` is important here constructor: function () { // Calling the super constructor is important so our generator is correctly set up generators.Base.apply(this, arguments); // Next, add your custom code this.option('coffee'); // This method adds support for a `--coffee` flag } });
module.exports = generators.Base.extend({ method1: function () { console.log('method 1 just ran'); }, method2: function () { console.log('method 2 just ran'); } });
下一步的時候當你運行generator的時候,會看到這兩句console輸出在控制檯。
在項目跟路徑下 generator-name(vue)/
執行指令:
npm link
過程當中,將會安裝node模塊依賴,和建立軟鏈接指向你當前項目。
//1.到本地全局node模塊路徑下 cd /usr/local/lib/node_modules //2.查看列表 ll //3.會看到已經安裝了一個全局的geneator-vue模塊 npm geneator-vue -> /Users/lvjinlong/generator-vue gulp .. //4.此時在任意新建的項目文件夾中yo項目的名字,會看到上面實例中的console打印出來的結果。 yo vue
安裝geneator的時候,Yeoman會搜索你的文件夾,會把包含 .yo-rc.json
文件的文件夾做爲你的根目錄來初始化項目。
問:那麼,.yo-rc.json
是個什麼東西呢?
答:當你 第一次 調用this.config.save()
的時候,系統會生成這個文件。問:那麼,
this.config.save()
這個方法的做用是什麼呢?
答:官網 這篇文章會有講解,大致意思是會利用.yo-rc.json
來存儲或是讀取用戶相關信息。
因此當你初始化一個項目的時候,別忘記清除掉以前系統生成的.yo-rc.json
。
原文地址:http://yeoman.io/authoring/running-context.html
每一個方法會直接附加在generator原型上做爲一個action,每一個action按照必定的循序執行在Yeoman的生命週期中。
這些方法至關於直接執行了 Object.getPrototypeOf(generator)
,
全部方法都會 自動執行 。若是不想都自動執行,請往下看。
只有私有方法在Yeoman中才不會自動執行,下面有三種辦法幫你建立一個私有方法。
_method
)generators.Base.extend({ init: function () { this.helperMethod = function () { console.log('won\'t be called automatically'); }; }; });
var MyBase = generators.Base.extend({ helper: function () { console.log('won\'t be called automatically'); } }); module.exports = MyBase.extend({ exec: function () { this.helper(); } });
Yeoman中的定義了生命週期鉤子,和這些鉤子命名相同的會按照順序執行,若是和這些鉤子名稱不同則默認爲 default
這些生命週期鉤子 按順 序爲:
原文地址:http://yeoman.io/authoring/user-interactions.html
Yeoman默認在終端中執行,可是也支持在多種不一樣工具中執行。這時候咱們使用 console.log()
或是 process.stdout.write()
用戶就可能看不到,Yeoman中使用 generator.log()
來統一打印輸出結果。
提示框是Yeoman主要和用戶交流的手段,是經過Inquirer模塊來實現的,全部的API及參數能夠看這裏,執行如下實例看下效果:
module.exports = generators.Base.extend({ prompting: function () { var done = this.async(); this.prompt({ type : 'input', name : 'name', message : 'Your project name', default : this.appname // Default to current folder name }, function (answers) { this.log(answers.name); done(); }.bind(this)); } })
一個肯定的答案,好比賬號,用戶可能屢次提交同一個答案,這時候能夠用Yeoman提供 store
來存儲這些答案。
this.prompt({ type : 'input', name : 'username', message : 'What\'s your Github username', store : true }, callback);
這時候會在跟路徑下生成一個.yo-rc.json
文件,裏面會存儲name信息。能夠參考官網storage這一節
參數直接經過命令行傳遞,例如:
yo webapp my-project
這個例子中,my-project 是第一個參數。
通知系統咱們須要參數,咱們使用 generator.argument()
方法,這個方法接受兩種形式:
hash(key-value) -- 哈希值的形式,接受如下參數做爲key值
var _ = require('lodash'); //須要提早安裝lodash模塊,提供一些經常使用方法 module.exports = generators.Base.extend({ //注: arguments和options必須在constructor中定義. constructor: function () { generators.Base.apply(this, arguments); //appname爲一個必須的參數 this.argument('appname', { type: String, required: true }); //用駝峯式把這個參數保存起來 this.appname = _.camelCase(this.appname); } });
Options(選項)看起來像是Arguments(參數),可是他們是在命令行中的標誌。
實例:舉一個官網團隊的腳手架demo - webapp - 15行
module.exports = generators.Base.extend({ constructor: function () { generators.Base.apply(this, arguments); this.option('skip-welcome-message', { desc: 'Skips the welcome message', type: Boolean }); } })
yo webapp --skip-install
輸出信息使用 generator.log
模塊,和js的 console.log()
基本一致。
module.exports = generators.Base.extend({ myAction: function () { this.log('Something has gone wrong!'); } });
傳值的方式同Arguments(參數),字符串或hash。區別是參數:
* desc:描述 * alias:簡寫(--version 簡寫爲 -v) * type:[ Boolean | String | Number ] * defaults:默認值 * hide :[ Boolean ] 是否隱藏幫助信息
原文地址:http://yeoman.io/authoring/composability.html
頗有趣的是,官網的第一個demo居然是一個變形金剛組合的gif,可見他們是多麼想表達各個小功能組合起來後的yeoman是有多強大。
能夠經過如下兩種方式開始組合:
generator-backbone
使用 generator-mocha
)。sass
或者 less
來搭配 webpack
或是 gulp
)generator.composeWith()
composeWith
方法容許你的generator來組合別人的generator,可是一旦組合成功,不要忘記第二章的內容 <(二)Running Context 生命週期>,全部被組合的generator都遵循Yeoman的生命週期規則來順序執行,不一樣的generator執行順序,取決於composeWith
調用他們的順序,看下面的API及執行順序實例。
composeWith
接收三個參數:
namespace
:聲明generator和誰組合。[ String ]options
:調用generator的時候須要接收的參數。[ Object | Array ]settings
:你的generator用這些配置來決定若是運行其餘的generators。[ Object ]
settings.local
:須要在 dependencies
中配置,使用dependencies安裝的模塊至關於本地模塊,這裏使用 require.resolve
來返回一個本地模塊的路徑,如:node_modules/generator-name
[ String ]settings.link
:weak
or strong
[ String ]
week
link:在初始化的時候不運行,好比後端運行的,frameworks或css的預處理。strong
link:一直運行。當須要用 peerDependencies
來組合generator
this.composeWith('backbone:route', { options: { rjs: true }});
當須要用 dependencies
來組合generator
this.composeWith('backbone:route', {}, { local: require.resolve('generator-bootstrap') }); //注:require.resolve()將返回node.js須要的模塊路徑。
接下來4.2中會解釋 peerDependencies
和 dependencies
的區別。
// In my-generator/generators/turbo/index.js module.exports = require('yeoman-generator').Base.extend({ 'prompting' : function () { console.log('prompting - turbo'); }, 'writing' : function () { console.log('writing - turbo'); } }); // In my-generator/generators/electric/index.js module.exports = require('yeoman-generator').Base.extend({ 'prompting' : function () { console.log('prompting - zap'); }, 'writing' : function () { console.log('writing - zap'); } }); // In my-generator/generators/app/index.js module.exports = require('yeoman-generator').Base.extend({ 'initializing' : function () { this.composeWith('my-generator:turbo'); this.composeWith('my-generator:electric'); } });
來分析下上面這段腳本:
composeWith
方法 turbo 和 electric。因此執行後的結果以下:
prompting - turbo prompting - zap writing - turbo writing - zap
peerDependencies
和 dependencies
的區別npm容許如下三種dependencies(依賴):
dependencies
:使用依賴,本身或是別人使用你的generator所必備的依賴模塊。這些模塊被generator視爲本地模塊。peerDependencies
:看下面的 注: npm@3後,peerDependencies不會再被自動安裝,須要手動。devDependencies
:開發依賴,做爲開發或者是測試須要用的模塊,若是別人安裝你的generator,這些模塊不該該被安裝。當使用 peerDependencies
別的模塊也要依賴當前這個模塊,當心不要建立版本致使衝突,Yeoman推薦使用(>=) 或 (*) 來安裝可用的版本,如:
{ "peerDependencies": { "generator-gruntfile": "*", "generator-bootstrap": ">=1.0.0" } }
注:npm@3之後,peerDependencies
不會再被自動安裝,安裝他們必須執行以下:
npm install generator-yourgenerator generator-gruntfile generator-bootstrap@">=1.0.0"
原文地址:http://yeoman.io/authoring/dependencies.html
Yeoman提供如下幾種形式來安裝依賴。
使用 generator.npmInstall()
來安裝npm包,若是你在多個generators調用了 npm install
Yeoman保證只會執行一次。
例如:你須要安裝 lodash 這個模塊做爲發開依賴。
generators.Base.extend({ installingLodash: function() { this.npmInstall(['lodash'], { 'saveDev': true }); } });
效果等同於直接在終端輸入:
npm install lodash --save-dev
使用 generator.bowerInstall()
來安裝依賴。實例:同npm。
使用 generator.installDependencies()
來同時安裝npm 和 bower。實例:同npm。
可使用 spawnCommand
來安裝其餘工具。好比:PHP的composer。
原文地址:http://yeoman.io/authoring/file-system.html
Yeoman會在這個根路徑中建立你項目的腳手架。
根路徑會以如下兩種方式定義:
.yo-rc.json
的路徑你能夠經過Yeoman提供的 generator.destinationRoot()
方法來獲取根路徑,這個方法接收一個參數 generator.destinationPath('sub/path')
來獲取子目錄的路徑。
例如:
查看當前路徑
$ pwd ~/projects
//跟路徑是 ~/projects generators.Base.extend({ paths: function () { this.destinationRoot(); // returns '~/projects' this.destinationPath('/sub/index.js'); // returns '~/projects/sub/index.js' } });
原文是Template context,其實我感受直譯不太好,換作叫經常使用工做路徑會更好。
這個路徑的默認取你當前目錄 ./templates/
, 能夠手動覆蓋這個路徑 generator.sourceRoot('new/template/path')
例如:
generators.Base.extend({ paths: function () { this.sourceRoot(); //設置經常使用工做路徑 // returns './templates' this.templatePath('index.js'); //讀取經常使用工做路徑 // returns './templates/index.js' } });
全部文件相關的方法都會經過 this.fs
暴露出來。這裏有全部文件操做相關方法,包括下面的copyTpl
方法。
實例: 把一個 經常使用工做路徑
的文件複製到 根路徑
下,並傳一個參數。
./templates/index.html
內容是:<html> <head> <title><%= title %></title> </head> </html>
copyTpl
方法把來複制文件,該方法使用ejs模板語法 generators.Base.extend({ writing: function () { this.fs.copyTpl( this.templatePath('index.html'),//第一個參數:from this.destinationPath('public/index.html'),//第二個參數:to { title: 'Templating with Yeoman' }//第三個參數:options ); } });
public/index.html
<html> <head> <title>Templating with Yeoman</title> </head> </html>
Yeoman提供 registerTransformStream()
方法,使用gulp的來操做文件。
例如:
var beautify = require('gulp-beautify'); this.registerTransformStream(beautify({indentSize: 2 }));
Yeoman介紹了幾個比較流行的解析器:
var cheerio = require('cheerio'), $ = cheerio.load('<h2 class="title">Hello world</h2>'); $('h2.title').text('Hello there!'); $('h2').addClass('welcome'); $.html(); //=> <h2 class="title welcome">Hello there!</h2>
本次只翻譯了前六章,後續會翻譯後六章、本身若是寫一個generator以及遇到的坑和問題。都會更新在個人github的Yeoman-article中。