要通過yeoman來將generator裏相應的內容放到本地項目中,我們首先要在全局安裝yo
npm i yo -g
接下來全局安裝對應的generator
npm i generator-<name> -g
cd到相應的目錄下,通過yo運行generator,就可以將相應內容放到本地
yo <name>
除了網上可以找到的相應generator外,我們也可以自己寫一個generator
實現簡單的generator來將文件寫入本地
新建一個文件夾,文件夾的名字要以generator-開頭,後面接一個名字,在後面的指令中需要用到
我在這裏新建了一個generator-test文件夾,使用npm init初始化package.json,然後將yeoman-generator的npm包下載到本地項目
mkdir generator-test
cd generator-test
npm init
npm i yeoman-generator
在項目建好後,在項目中新建app/generator/index.js做爲Generator核心入口,導出一個繼承自Generator的類型,在yeoman-generator工作是會執行一些相應的方法,我們可以在這些方法中進行一些操作,比如寫入文件等操作
const Generator = require("yeoman-generator");
module.exports = class extends Generator{ // 導出繼承自Generator的一個類
writing(){ // Generator將文件寫入本地的方法
// 調用Generator的fs中的write方法來寫入文件 第一個參數爲寫入的絕對路徑,第二個參數爲寫入內容
this.fs.write(
this.destinationPath("test.txt"),
Math.random().toString()
)
}
}
然後使用npm link將這個模塊鏈接到全局
npm link
然後退出這個項目,另建一個文件夾,使用yo 指令來執行模塊的相應操作,這裏的就是我們之前創建項目時,generator-後面的內容
cd ..
mkdir test-proj
cd test-proj
yo test
打開新建的test-proj文件夾,可以看到有一個新的test.txt文件,裏面寫着一個隨機數
要注意的是,yo 這裏的name實際上不是看文件夾的名字的,而是看package.json中的name屬性中generator-後面的內容,如果只是改文件夾名的話是無法修改的
通過模板實現文件加載到本地
在上面已經提到了如何將文件寫入到本地,但是一個個的文件寫入很是麻煩,我們要的應該是像使用腳手架工具的時候,一個命令就能將很多內容下載到本地的操作,這種操作我們可以通過模板來實現
新建一個generator-temp文件夾,執行各種初始化操作
npm init
npm i yeoman-generator
在項目中創建下列的目錄
與上面直接寫入文件的generator的文件目錄不同的是,我們在app文件夾下創建了templates文件夾,這個文件夾是用來存放要寫入本地的模板文件,我們在這個文件夾下創建一個temp.txt,寫入一些相應的內容,在templates下的文件可以使用ejs語法,我們寫入如下內容
這是一個模板文件
<%= title%>
在index.js中寫入如下內容
const Generator = require("yeoman-generator");
module.exports = class extends Generator{ // 導出繼承自Generator的一個類
writing(){ // Generator將文件寫入本地的方法
// 通過模板方式實現文件寫入
// 模板文件路徑
const temp = this.templatePath("temp.txt")
// 輸出文件路徑
const output = this.destinationPath("temp.txt")
// 模板數據上下文
const content = {title:"這是ejs的title內容"}
this.fs.copyTpl(temp,output,content)
}
}
用npm link
將模板鏈接到全局
去到一個文件夾中執行yo temp
,新建了一個temp.txt文件,寫着
這是一個模板文件
這是ejs的title內容
寫入模板中的文件夾
如果我們要寫入一個文件夾的話,我們只需要寫入文件夾名就可以了,將index.js代碼改爲下面這樣
const Generator = require("yeoman-generator");
module.exports = class extends Generator{ // 導出繼承自Generator的一個類
writing(){ // Generator將文件寫入本地的方法
// 通過模板方式實現文件寫入
// 模板文件路徑
const temp = this.templatePath("demo")
// 輸出文件路徑
const output = this.destinationPath("demo")
// 模板數據上下文
const content = {title:"這是ejs的title內容"}
this.fs.copyTpl(temp,output,content)
}
}
在templates文件夾下新建demo文件夾,demo文件夾下寫入index.html和style.css,執行npm link,到測試文件夾下執行yo temp發現demo文件夾被寫入了
響應用戶的輸入
用過腳手架的朋友們都知道,我們使用一個腳手架的時候,命令行總是會出現各種問題,而根據我們的問題,初始化的內容也不一樣,這裏是用到了prompting方法,在這個方法內接受用戶的鍵入,將其存儲到類本身的某個屬性中,在writing中找到這個屬性獲取相應的值,根據相應的值獲取不同的模板
將index.js改成
const Generator = require("yeoman-generator");
module.exports = class extends Generator{ // 導出繼承自Generator的一個類
prompting(){
// 調用Generator的prompt方法來發出對用戶的命令行詢問
// prompt接收一個數組參數,每個數組成員是一個問題的信息
return this.prompt([{
type:"input", // 問題的類型
name:"title", // 最終得到結果的一個屬性名
message:"your title is", // 詢問的問題內容
default:"123" // 默認值
}]).then(answer=>{
this.answer = answer // 將得到的答案賦值this.answer
})
}
writing(){ // Generator將文件寫入本地的方法
// 通過模板方式實現文件寫入
// 模板文件路徑
const temp = this.templatePath("temp.txt")
// 輸出文件路徑
const output = this.destinationPath("temp.txt")
// 模板數據上下文
const content = this.answer
this.fs.copyTpl(temp,output,content)
}
}
執行npm link鏈接到全局,接下來去到一個空文件夾,執行yo temp,看到了如下的問題
顯然括號內的123就是我們設定好的默認值,而“your title is”就是我們的問題,隨便寫個zem進去敲下回車
查看創建的temp.txt
完全符合預期
yeoman-generator寫入方法的優先級順序
上面我們寫入了兩個方法,一個prompting方法,一個writing方法,實際上,寫在這裏的方法有一定的優先級順序,在官網找到了相應的順序,官網內容如下
- initializing - Your initialization methods (checking current project state, getting configs, etc)
- prompting - Where you prompt users for options (where you’d call this.prompt())
- configuring - Saving configurations and configure the project (creating .editorconfig files and other metadata files)
- default - If the method name doesn’t match a priority, it will be pushed to this group.
- writing - Where you write the generator specific files (routes, controllers, etc)
- conflicts - Where conflicts are handled (used internally)
- install - Where installations are run (npm, bower)
- end - Called last, cleanup, say good bye, etc
按官網的順序,寫入的方法名字和上面的名字相同時,按上面的名字優先級順序處理,如果與上面名字不同,則按default的優先級處理