yeoman使用

Study Notes

本博主會持續(xù)更新各種前端的技術盈蛮,如果各位道友喜歡,可以關注械念、收藏沈条、點贊下本博主的文章牙瓢。

yeoman

現(xiàn)代 Web 應用程序的 Web 腳手架工具

  • 全局安裝 yo
npm i yo -g

安裝對應的 generator

這里安裝generator-none

npm i generator-node -g

用法

  • 通過 yo 運行 generator
mkdir my-module
cd my-module
yo node
  • 子生成器使用

如果不需要主生成器提供的所有功能僧凰,則仍可以通過直接與子生成器組合來使用羡儿。

可以通過運行下面的命令來查看每個子生成器的選項败匹。

yo node:sub --help

這里我們使用 node:cli 子生成器

yo node:cli

link 到全局

npm link

查看是否 link 到全局

my-module --help

yeoman 使用步驟總結

  • 1撮胧、明確你的需求
  • 2桨踪、找到合適的 Generator
  • 3、全局安裝 Generator
  • 4芹啥、通過 yo 運行對應的 Generator
  • 5锻离、通過命令行交互填寫選項
  • 6、生成你所需要的項目結構

自定義 Generator

生成器的核心是 Node.js 模塊墓怀。

首先汽纠,創(chuàng)建一個文件夾,在其中編寫 generator傀履。 該文件夾必須命名為 generator-name(其中 name 是你的生成器的名稱)虱朵。 這一點很重要,因為 Yeoman 依靠文件系統(tǒng)來查找可用的生成器钓账。

進入 Generator 文件夾后碴犬,創(chuàng)建一個 package.json 文件。 該文件是 Node.js 模塊清單官扣。 你可以通過從命令行運行 npm init 或手動輸入以下內容來生成此文件:

{
  "name": "generator-name",
  "version": "0.1.0",
  "description": "",
  "files": ["generators"],
  "keywords": ["yeoman-generator"],
  "dependencies": {
    "yeoman-generator": "^1.0.0"
  }
}

name 屬性必須以 generator-為前綴翅敌。 關鍵字屬性必須包含yeoman-generator羞福,并且存儲庫必須具有要由我們的 generators 頁面建立索引的描述惕蹄。

你應該確保將最新版本的 yeoman-generator 設置為依賴項。 你可以通過運行以下命令執(zhí)行此操作:

npm install --save yeoman-generator

files 屬性必須是生成器使用的文件和目錄的數(shù)組。

根據(jù)需要添加其他 package.json 屬性卖陵。

Generator 目錄結構

Yeoman 的功能取決于你如何構建目錄樹遭顶。 每個子生成器都包含在其自己的文件夾中。

調用你的名字時使用的默認生成器是應用生成器泪蔫。 它必須包含在app/目錄中棒旗。

調用yo name:subcommand 時使用的子生成器存儲在與 sub 命令完全相同的文件夾中。

在一個示例項目中撩荣,目錄樹可能如下所示:

└───generators/........................生成器目錄
    ├───app/...........................默認生成器目錄
    │   └───index.js..................默認生成器實現(xiàn)
    └───router/........................其他生成器目錄
        └───index.js...................其他生成器實現(xiàn)
├───package.json.......................模塊包配置文件

該生成器將顯示yo nameyo name:router 命令铣揉。

Yeoman 允許兩種不同的目錄結構。 它會在./generators/中查找以注冊可用的生成器餐曹。

前面的示例也可以編寫如下:

├───app/...............................默認生成器目錄
│   └───index.js......................默認生成器實現(xiàn)
└───router/............................其他生成器目錄
    └───index.js.......................其他生成器實現(xiàn)
├───package.json.......................模塊包配置文件

如果使用第二個目錄結構逛拱,請確保將 files 屬性指向 package.json 所有生成器文件夾。

{
  "files": ["app", "router"]
}

擴展 Generator

有了此結構后台猴,就可以編寫實際的生成器了朽合。

Yeoman 提供了一個基本生成器,你可以擴展它來實現(xiàn)自己的行為饱狂。 該基本生成器將添加你希望簡化任務的大多數(shù)功能曹步。

在生成器的index.js 文件中,以下是擴展基本生成器的方法:

const Generator = require('yeoman-generator');

module.exports = class extends Generator {};

我們將擴展的生成器分配給 module.exports 以使其可用于生態(tài)系統(tǒng)休讳。 這就是我們在 Node.js 中導出模塊的方式讲婚。

覆蓋構造函數(shù)

某些生成器方法只能在構造函數(shù)內部調用。 這些特殊方法可能會執(zhí)行諸如設置重要狀態(tài)控件之類的操作衍腥,并且可能無法在構造函數(shù)之外運行磺樱。

要覆蓋生成器構造函數(shù),請?zhí)砑右粋€構造函數(shù)方法婆咸,如下所示:

const Generator = require('yeoman-generator');

module.exports = class extends Generator {
  // The name`constructor` is important here
  constructor(args, opts) {
    // Calling the super constructor is important so our generator is correctly set up
    super(args, opts);

    // Next, add your custom code
    this.option('babel'); // This method adds support for a`--babel` flag
  }
};

添加功能

調用生成器后竹捉,添加到原型的每種方法都會運行,并且通常是按順序進行的尚骄。 但是块差,正如我們將在下一節(jié)中看到的那樣,一些特殊的方法名稱將觸發(fā)特定的運行順序倔丈。

示例:

const Generator = require('yeoman-generator');

module.exports = class extends Generator {
  method1() {
    this.log('method 1 just ran');
  }

  method2() {
    this.log('method 2 just ran');
  }
};

當我們運行生成器時憨闰,將在控制臺看到日志輸出。

示例二:

// 此文件作為Generator的核心入口
// 需要導出一個繼承自Yeoman Generator的類型
// Yeoman Generator在工作時會自動調用我們在此類型中定義的一些生命周期方法
// 我們在這些方法中可以調用父類提供的一些工具方法來實現(xiàn)一些功能需五,例如文件寫入
const Generator = require('yeoman-generator');

module.exports = class extends Generator {
  // Yeoman 自動在生成文件階段調用次方法
  writing() {
    // Generator將文件寫入本地的方法
    // 調用Generator的fs中的write方法來寫入文件  第一個參數(shù)為寫入的絕對路徑鹉动,第二個參數(shù)為寫入內容
    this.fs.write(this.destinationPath('temp.txt'), '1231');
  }
};

運行 generator

接下來我們將運行 generator,看看它是否有效宏邮。

由于我是在本地開發(fā)生成器泽示,因此尚未作為全局 npm 模塊提供缸血。 可以使用 npm 創(chuàng)建一個全局模塊并將其符號鏈接到本地模塊。

在文件夾根目錄下械筛,執(zhí)行:

npm link

文件系統(tǒng)的使用

位置上下文和路徑

Yeoman 文件實用程序基于這樣一個理念:磁盤上總是有兩個位置有上下文捎泻。這些上下文是生成器最有可能讀取和寫入的文件夾。

目標上下文

第一個上下文是目標上下文埋哟。 目標是 Yeoman 將在其中存放新應用程序的文件夾笆豁。 這是你的用戶項目文件夾,你將在其中編寫大多數(shù)腳手架赤赊。

目標上下文定義為當前工作目錄或包含.yo-rc.json 文件的最近的父文件夾闯狱。.yo-rc.json 文件定義了 Yeoman 項目的根目錄。 該文件允許你的用戶在子目錄中運行命令并使它們在項目上運行抛计。 這樣可以確保最終用戶的行為一致扩氢。

你可以使用this.destinationRoot()或通過使用this.destinationPath('sub/path')聯(lián)接路徑來獲取目標路徑。

// Given destination root is ~/projects
class extends Generator {
  paths() {
    this.destinationRoot();
    // returns '~/projects'

    this.destinationPath('index.js');
    // returns '~/projects/index.js'
  }
}

模板上下文

模板上下文是用于存儲模板文件的文件夾爷辱。 通常是你要從中讀取和復制的文件夾录豺。

默認情況下,模板上下文定義為./templates/饭弓。 你可以使用this.sourceRoot('new/template/path')覆蓋此默認值双饥。

你可以使用this.sourceRoot()或通過使用this.templatePath('app/index.js')連接路徑來獲取路徑值。

class extends Generator {
  paths() {
    this.sourceRoot();
    // returns './templates'

    this.templatePath('index.js');
    // returns './templates/index.js'
  }
};

“內存中”文件系統(tǒng)

Yeoman 在覆蓋用戶文件時非常小心弟断。 基本上咏花,在預先存在的文件上發(fā)生的每個寫入都將經(jīng)歷沖突解決過程。 此過程要求用戶驗證將內容覆蓋到其文件的每個文件寫入阀趴。

此行為可防止出現(xiàn)意外情況并限制發(fā)生錯誤的風險昏翰。 另一方面,這意味著每個文件都異步寫入磁盤刘急。

由于異步 API 難以使用棚菊,因此 Yeoman 提供了一個同步文件系統(tǒng) API,其中每個文件都被寫入內存文件系統(tǒng)叔汁,并且只有在 Yeoman 完成運行后才被寫入磁盤统求。

此內存文件系統(tǒng)在所有組合的生成器之間共享。

文件工具

生成器在this.fs上公開了所有文件方法据块,此文件是 mem-fs-editor-確保檢查模塊文檔中所有可用的方法码邻。

值得注意的是,盡管this.fs公開了commit另假,但您不應在生成器中調用它像屋。 在運行循環(huán)的沖突階段之后,Yeoman 在內部調用此方法边篮。

示例:復制模板文件

這是我們要復制和處理模板文件的示例己莺。

文件路徑app/templates/index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title><%= Title %></title>
  </head>
  <body></body>
</html>

然后因苹,在將內容作為模板處理時,我們使用copyTpl方法復制文件篇恒。copyTpl 使用 ejs 模板語法

class extends Generator {
  writing() {
    this.fs.copyTpl(
      this.templatePath('index.html'),
      this.destinationPath('public/index.html'),
      { title: 'Templating with Yeoman' }
    );
  }
}

一種非常常見的情況是在提示階段存儲用戶輸入凶杖,并將其用于模板:

class extends Generator {
  async prompting() {
    this.answers = await this.prompt([{
      type    : 'input',
      name    : 'title',
      message : 'Your project title',
    }]);
  }

  writing() {
    this.fs.copyTpl(
      this.templatePath('index.html'),
      this.destinationPath('public/index.html'),
      { title: this.answers.title } // user answer `title` used
    );
  }
}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末胁艰,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子智蝠,更是在濱河造成了極大的恐慌腾么,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杈湾,死亡現(xiàn)場離奇詭異解虱,居然都是意外死亡,警方通過查閱死者的電腦和手機漆撞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門殴泰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人浮驳,你說我怎么就攤上這事悍汛。” “怎么了至会?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵离咐,是天一觀的道長。 經(jīng)常有香客問我奉件,道長宵蛀,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任县貌,我火速辦了婚禮术陶,結果婚禮上,老公的妹妹穿的比我還像新娘煤痕。我一直安慰自己瞳别,他們只是感情好,可當我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布杭攻。 她就那樣靜靜地躺著祟敛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪兆解。 梳的紋絲不亂的頭發(fā)上馆铁,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天,我揣著相機與錄音锅睛,去河邊找鬼埠巨。 笑死历谍,一個胖子當著我的面吹牛,可吹牛的內容都是我干的辣垒。 我是一名探鬼主播望侈,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼勋桶!你這毒婦竟也來了脱衙?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤例驹,失蹤者是張志新(化名)和其女友劉穎捐韩,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鹃锈,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡荤胁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了屎债。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仅政。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖盆驹,靈堂內的尸體忽然破棺而出已旧,到底是詐尸還是另有隱情,我是刑警寧澤召娜,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布运褪,位于F島的核電站,受9級特大地震影響玖瘸,放射性物質發(fā)生泄漏秸讹。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一雅倒、第九天 我趴在偏房一處隱蔽的房頂上張望璃诀。 院中可真熱鬧,春花似錦蔑匣、人聲如沸劣欢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽凿将。三九已至,卻和暖如春价脾,著一層夾襖步出監(jiān)牢的瞬間牧抵,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留犀变,地道東北人妹孙。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像获枝,于是被迫代替她去往敵國和親蠢正。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,781評論 2 361