前端工程化---构造简单的微信小程序开发脚手架工具

这篇博客要说的脚手架工具我以前发布到npm上了,是generator-wxfile的1.1.1版本,后面可能还会继续有版本更新,所以要测试功能的话要下载对应的版本

基本功能

在我的另一篇文章前端工程化 发布一个自动生成微信开发文件的npm包中,我使用yeoman实现了重复文件的生成,而在这里我使用plop来实现这个功能,使用yeoman来将一开始的文件拉到本地,要完成的有以下几个功能

  1. 询问用户构建的项目名,默认为文件夹名,写入project.config.json文件中
  2. 询问用户构建时使用的APPID,这里的APPID只是写入project.config.json文件
  3. 询问用户构建项目时默认的页面的文件名,构建相应的文件夹和文件,在app.json中写入相应的路由
  4. 询问用户是否启用plop来快速构建重复文件,是的话就将plopfile.js和模板文件加入到项目中
  5. 通过plop工具将重复文件写入pages文件夹中,在app.json中写入相应的路由

文件目录

基本的文件目录和前端工程化 发布一个自动生成微信开发文件的npm包文章中的文件目录一样,只是模板文件有些不同,修改了index.js文件的内容,这里plop-temp和tempPage里面的文件一样,除了替换文本的语法不同,tempPage文件中的替换文本是使用yeoman写入的,所以是使用ejs语法,采用<%= prop%>的语法,而在plop-temp文件夹中的文件是在采用plop工具的时候使用的模板工具,使用的语法来代替
在这里插入图片描述
这里templates的文件基本上是我使用微信开发者工具简单初始化后拿过来做为初始化文件模板的,也可以直接去我的github上把文件拉下来看看

yeoman实现初始化过程


询问用户

上面说到了,我要实现向用户询问的功能,这里可以使用inquire这个npm包,但是因为yeoman里面已经有这个功能了,所以我就直接使用yeoman-generator的prompt方法了

首先要引入yeoman-generator包,导出一个类,在prompting方法中调用this.prompt方法,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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模块,代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
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
完整代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
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

1
npm i yo

接下来就执行

1
yo wxfile

根据问题就可以生成相应文件了
如果选择使用plop工具,本地没有plop的话,直接

1
npm i

就可以将plop做为开发依赖放到项目中,执行

1
plop wxfile

就可以使用相应功能了