脚手架的基础
首先须要新建一个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,到此咱们的脚手架就成功完成了!