腳手架的基礎
首先須要新建一個package.json文件,並在配置裏添加"bin"屬性,"bin"的值爲文件路徑。javascript
PS:若是你想自定義CLI啓動的名字,能夠給bin一個對象,鍵值就是你啓動輸入的名字,不過你開發項目的時候要注意不要跟其餘的CLI名稱重複了。不自定義名稱的話,就是輸入項目的名稱便可。本次演示我就不取自定義名稱了,想自定義名稱的小夥伴記得啓動項目時,須要用自定義的名稱(以下圖)。html
CLI應用的入口文件必需要有 #!/usr/bin/env node 做爲文件頭,若是使用的是Linux和macOS系統的話,還須要將此文件的讀寫權限改成755。java
接着咱們經過yarn link的方式將此模塊link到全局 ,來看看這個項目的能不能跑起來。node
能夠看到打出了log的信息,就表明項目正常執行了,腳手架的基礎已經建好了。json
PS:這裏若是執行不了,多是環境變量配置有問題,你能夠用'yarn global bin'去查看你的yarn全局Bin的地址,並加到環境變量中就能夠了。ui
腳手架的工做過程
接下來,咱們來編寫腳手架的工做過程,其過程分爲兩點:1.經過命令行交互詢問用戶問題;2.根據用戶回答的結果生成文件。spa
經過命令行交互詢問用戶問題
在node裏想使用命令行對用戶發起詢問,須要使用‘inquirer’這個模塊,因此須要先安裝這個模塊,能夠用yarn add來加載。命令行
yarn add inquirer
安裝好後,將quirer引入cli,inquirer有個prompt方法,能夠經過傳遞相關配置,用這個方法來對用戶進行詢問,詢問完後,經過‘.then’來得到用戶的輸入值。3d
#!/usr/bin/env node // console.log('cli working') const inquirer = require('inquirer'); inquirer.prompt([ { type: 'input', //指定問題的輸入方式 name: 'name', //指定問題返回值的鍵名 message: 'Project name?' //給用戶的提示 } ]).then( answer => { console.log(answer); });
咱們回到控制檯看看可否進行詢問並返回。code
咱們能夠看到詢問和返回都是沒有問題的,咱們的詢問這一步就完成了
根據用戶回答的結果生成文件
如今咱們須要根據回答生成文件,生成的文件須要模板,因此咱們要先創建模板文件,模板文件可使用<%= name %>來填入剛纔回答的問題,若是你剛剛在prompt中name的value值用的是別的,這裏就把name換成你本身寫的value值便可。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title><%= name %></title> </head> <body> </body> </html>
在生成模板文件以前,咱們通常先要把模板的根目錄和目標路徑給肯定下來
#!/usr/bin/env node // console.log('cli working') const inquirer = require('inquirer'); const path = require('path'); inquirer.prompt([ { type: 'input', //指定問題的輸入方式 name: 'name', //指定問題返回值的鍵名 message: 'Project name?' //給用戶的提示 } ]).then( answer => { // console.log(answer); // 模板目錄 const tmplDir = path.join(__dirname, '../temp') // 目標目錄 const destDir = process.cwd() });
在肯定了路徑以後,咱們再經過fs去讀取模板目錄下的目標文件,再將讀取到的文件經過模板引擎渲染文件並轉化到目標路徑,這裏須要經過'yarn add ejs'下載模板引擎。
#!/usr/bin/env node // console.log('cli working') const inquirer = require('inquirer'); const path = require('path'); const fs = require('fs'); const ejs = require('ejs') inquirer.prompt([ { type: 'input', //指定問題的輸入方式 name: 'name', //指定問題返回值的鍵名 message: 'Project name?' //給用戶的提示 } ]).then( answer => { // console.log(answer); // 模板目錄 const tmplDir = path.join(__dirname, '../temp') // 目標目錄 const destDir = process.cwd() // 將模板下的文件所有轉換到目標目錄 fs.readdir(tmplDir, (err, files) => { if (err) throw err files.forEach(file => { // 經過模板引擎渲染文件 ejs.renderFile(path.join(tmplDir, file), answer, (err, result) => { if (err) throw err // 將結果寫入目標文件路徑 fs.writeFileSync(path.join(destDir, file), result) }) }) }) });
完成以後,這個腳手架就完成搭建了!
嘗試使用新搭建的腳手架
咱們創建一個新的目錄,並在下面去執行咱們的腳手架命令
能夠看到新建的文件夾裏生成了一個html文件,咱們打開看看這個文件是否是按照咱們的模板渲染生成的
能夠看到<title></title>標籤裏的name就是咱們輸入的demo,到此咱們的腳手架就成功完成了!