「这是我参与2022首次更文挑战的第37天,活动详情查看:2022首次更文挑战」
上一篇中,我们实现了一个只能输出日志的 generator,这篇我们来丰富一下功能。
用户交互 this.prompt
通过 prompt 可以实现用户交换,譬如获取用户输入、用户确认等基本操作。prompt 是个异步方法,参数为一个数组,数组中是要执行的交互操作。
交互操作对象
- type:交互类型(值可以是 input:输入,confirm:选择等);
- name:接收输入信息的变量名;
- message:命令行中输出的提示信息;
- default:输入的默认值;
我们把原来的 method1、method2 方法删除,换成下面的代码。
module.exports = class extends Generator {
constructor(args, opts) {
// Calling the super constructor is important so our generator is correctly set up
super(args, opts);
}
async setup() {
const ans = await this.prompt([{
type: 'input',
name: 'name',
message: 'Your project name.',
default: this.appname
}, {
type: 'confirm',
name: 'cool',
message: 'Would you like to enable the Cool feature?'
}])
this.log('app name:', ans.name)
this.log('cool featrue:', ans.cool)
}
};
再次执行 yo createapp
至此我们就完成了用户输入工作,通常的项目名称等需要收集用户输入信息。
文件系统,模板的使用
我们通常会将基础模块放在模板里,完成基础配置,然后使用模板来创建项目,下面我们来看 yeoman 的模板怎么使用。
第一步:在 generators 录下创建一个 templates 目录,用于存放模板。然后在 templates 创建 index.html 文件,加入以下代码
<html>
<head>
<title><%= appname %></title>
</head>
<body>Hello World.</body>
</html>
第二步:修改 generators/app/index.js 文件的代码如下
var Generator = require('yeoman-generator');
module.exports = class extends Generator {
constructor(args, opts) {
// Calling the super constructor is important so our generator is correctly set up
super(args, opts);
}
async setup() {
const ans = await this.prompt([{
type: 'input',
name: 'name',
message: 'Your project name.',
default: this.appname
}])
this.fs.copyTpl(this.templatePath('index.html'), this.destinationPath('public/index.html'), {
appname: ans.name
})
}
};
这里的 this.fs.copyTpl 可以用来拷贝一个模板到指定位置,并且带上替换模板文件中的变量对应的参数。this.templatePath 用于将一个相对路径转换成模板文件下的路径。this.destinationPath 用于将一个相对路径转换成输出的绝对路径。
第三步:执行 yo createapp 命令,输入 vue3
执行命令后,生成 /public/index.html 文件,并且用 vue3 替换模板文件中的 <%= appname %>。生成的文件如下
<html>
<head>
<title>vue3</title>
</head>
<body>Hello World.</body>
</html>
管理依赖
项目的依赖可以在 template 里增加 package.json 文件,也可以通过编程的方式创建该文件。
在 generators/app/index.js 文件中增加以下方法,this.fs.extendJSON() 创建 package.json 文件。
initPackage() {
const pkgJson = {
DevDependencies: {
eslint: '^3.15.0'
},
Dependencies: {
vue: '^3.2.31'
}
}
this.fs.extendJSON(this.destinationPath('public/package.json'), pkgJson)
this.npmInstall()
}
npmInstall 方法可以自动安装依赖,但该方法在 yeoman 5.0 后已经 deprecated 了,使用时需要注意 yeoman 当前版本
至此我们完成了初始化工具的雏形,下一节来改造成 vue 项目的 generator。