這篇博客要說的腳手架工具我以前發佈到npm上了,是generator-wxfile的1.1.1版本,後面可能還會繼續有版本更新,所以要測試功能的話要下載對應的版本
對最新的版本有什麼意見的話歡迎在評論中提出(σ′▽‵)′▽‵)σ
基本功能
在我的另一篇文章前端工程化 發佈一個自動生成微信開發文件的npm包中,我使用yeoman實現了重複文件的生成,而在這裏我使用plop來實現這個功能,使用yeoman來將一開始的文件拉到本地,要完成的有以下幾個功能
- 詢問用戶構建的項目名,默認爲文件夾名,寫入project.config.json文件中
- 詢問用戶構建時使用的APPID,這裏的APPID只是寫入project.config.json文件
- 詢問用戶構建項目時默認的頁面的文件名,構建相應的文件夾和文件,在app.json中寫入相應的路由
- 詢問用戶是否啓用plop來快速構建重複文件,是的話就將plopfile.js和模板文件加入到項目中
- 通過plop工具將重複文件寫入pages文件夾中,在app.json中寫入相應的路由
文件目錄
基本的文件目錄和前端工程化 發佈一個自動生成微信開發文件的npm包文章中的文件目錄一樣,只是模板文件有些不同,修改了index.js文件的內容,這裏plop-temp和tempPage裏面的文件一樣,除了替換文本的語法不同,tempPage文件中的替換文本是使用yeoman寫入的,所以是使用ejs語法,採用<%= prop%>的語法,而在plop-temp文件夾中的文件是在採用plop工具的時候使用的模板工具,使用{{prop}}的語法來代替
這裏templates的文件基本上是我使用微信開發者工具簡單初始化後拿過來做爲初始化文件模板的,也可以直接去我的github上把文件拉下來看看
yeoman實現初始化過程
詢問用戶
上面說到了,我要實現向用戶詢問的功能,這裏可以使用inquire這個npm包,但是因爲yeoman裏面已經有這個功能了,所以我就直接使用yeoman-generator的prompt方法了
首先要引入yeoman-generator包,導出一個類,在prompting方法中調用this.prompt方法,代碼如下
const Generator = require("yeoman-generator")
module.exports = class extends Generator{
prompting(){
return this.prompt([{ // 詢問用戶要創建的項目名稱
type:"input",
name:"projectName",
message:"your project name is",
default:this.appname // 項目所在文件夾的名稱
},{ // 詢問用戶的appID是多少
type:"input",
name:"appID",
message:"your appID is"
},{ // 詢問用戶初始化的第一個頁面名稱是什麼
type:"input",
name:"pageName",
message:"the initialized page name is",
default:"index" // 默認創建index頁面
},{ // 詢問用戶是否使用plop工具
type:"confirm",
name:"isPlop",
message:"do you use plop",
default:true // 默認使用
}]).then(answer=>{
this.answer = answer // 將回答放到answer屬性中
})
}
}
根據用戶的輸入寫入文件
上面我們獲取用戶的輸入到this.answer
中,在writing中我們通過這些答案來修改對應寫入的頁面的名字,上面獲取的pageName就是我們初始化時構建的page中文件夾的名字,以及該文件夾下js、json、wxss、wxml文件的名字,而且要根據上面獲取的isPlop來判斷是否將plop-temp文件夾的內容和plopfile.js文件加入到項目中,因爲涉及到文件夾的創建,所以這裏引入了fs模塊,代碼如下
const Generator = require("yeoman-generator")
const fs = require("fs")
module.exports = class extends Generator{
prompting(){
// ...
}
writing(){
const answer = this.answer
const pageName = answer.pageName
// 處理頁面模板文件
let tempPageFiles = ["tempPage.js","tempPage.json","tempPage.wxml","tempPage.wxss"]
.map(path=>"tempPage/"+path)
// 其他文件列表
let tempOtherFiles = ["app.js","app.json","app.wxss","project.config.json","sitemap.json","package.json"]
// 合併所有模板文件
let tempFiles = [...tempPageFiles,...tempOtherFiles]
// 處理頁面輸出文件
let outputPageFile = [`${pageName}.js`,`${pageName}.json`,`${pageName}.wxml`,`${pageName}.wxss`]
.map(path=>`pages/${pageName}/${path}`)
// 合併所有輸出文件
let outputFiles = [...outputPageFile,...tempOtherFiles]
if(answer.isPlop){ // 如果使用plop工具,則將相應的文件寫入
tempFiles=[...tempFiles,...["plop-temp","plopfile.js"]]
outputFiles=[...outputFiles,...["plop-temp","plopfile.js"]]
}
// 創建文件夾,在文件夾創建完成後調用回調函數執行文件寫入
fs.mkdir(`pages/${pageName}`,'1',()=>{
// 文件寫入
for(let i=0;i<tempFiles.length;i++){
this.fs.copyTpl(this.templatePath(tempFiles[i]),this.destinationPath(outputFiles[i]),answer)
}
})
}
}
需要替換文本的文件
要注意這裏的tempPage.js是tempPage文件夾中的,在temp-plop文件夾中的要使用另一種替換語法
plop實現重複文件的寫入
plopfile.js的編寫
這裏的plop工具要實現詢問用戶要新增的頁面的名字,根據這個名字創建文件,將路由寫入package.json文件中,因爲plop工具本身不具備讀寫文件的功能,我這裏又引入了fs模塊,使用plop.setActionType來實現一個新的type,在setGenerator的actions中使用這個type的action
完整代碼如下
const fs = require('fs')
module.exports = plop=>{
plop.setActionType('changeRouter',(answers,config,plop)=>{
fs.readFile('app.json',{},(err,data)=>{ // 讀取app.json文件
let d= JSON.parse(data.toString())
d.pages.push(`pages/${answers.pageName}/${answers.pageName}`) // 將當前新添加的內容寫入app.json
d = JSON.stringify(d,"","\t")
fs.writeFile('app.json',d,err=>{
if(err)
throw err
})
})
})
plop.setGenerator('wxfile',{ // 這裏的wxfile是一個自己設定的名字,在執行命令行的時候會用到
description:'create the repeat wxfile', // 這裏是對這個plop的功能描述
prompts:[{
type:'input', // 問題的類型
name:'pageName', // 問題對應得到答案的變量名,可以在actions中使用該變量
message:'your pageName is', // 在命令行中的問題
default:'page' // 問題的默認答案
}],
actions:[{
type:'add', // 操作類型,這裏是添加文件
path:'pages/{{pageName}}/{{pageName}}.json', // 添加的文件的路徑
templateFile:'plop-temp/tempPage.json' // 模板文件的路徑
},{
type:'add',
path:'pages/{{pageName}}/{{pageName}}.js',
templateFile:'plop-temp/tempPage.js'
},{
type:'add',
path:'pages/{{pageName}}/{{pageName}}.wxss',
templateFile:'plop-temp/tempPage.wxss'
},{
type:'add',
path:'pages/{{pageName}}/{{pageName}}.wxml',
templateFile:'plop-temp/tempPage.wxml'
},{ // 修改app.json裏面的路由
type:'changeRouter'
}]
})
}
需要替換文本的文件
使用方法
如果本地沒有yo的話,就全局安裝yo
npm i yo
接下來就執行
yo wxfile
根據問題就可以生成相應文件了
如果選擇使用plop工具,本地沒有plop的話,直接
npm i
就可以將plop做爲開發依賴放到項目中,執行
plop wxfile
就可以使用相應功能了