yeoman自定义脚手架使用心得
首先安装yo
1 |
|
安装mkdirp
用于创建多层目录
1 |
|
全局安装yeoman提供的写脚手架的脚手架 generator-generator
1 |
|
创建一个目录用于存放generator
1 |
|
下载generator模板
1 |
|
假设我要写一个 Generator 叫做 yzw-pc-web,根据Yeoman 的规定,你需要将这个 node 模块的名字命名为 generator-*,所以我命名为 generator-yzw-pc-web。keywords必须写成“yeoman-generator”。
回车添加一些脚手架信息
1 |
|
这个keywords一定要写
下载generator模板载成功后你可以在当前目录中找到generator-yzw-pc-web文件夹。
我们得到的generator目录
1 |
|
它并没有全局安装到node模块中,运行以下命令就可以在全局中使用。
npm link将本地项目放到本地全局的node_modules中,这样本地就能通过npm install generator-yzw-pc-web来安装这个包
1 |
|
往generator-yzw-pc-web里添加内容
进入generator-yzw-pc-web/generators/app/templates目录下创建package.json
1 |
|
我们的generator生成什么样的基础工程,目录结构,是否自动安装依赖模块等等都是在index.js文件完成的。可以先浏览下里面内容,然后把里面的内容删掉照着下面步骤来。
打开generator-yzw-pc-web/generators/app/index.js
首先加入依赖包
1 |
|
- 继承generator
1
2
3
4
5
6'use strict';
var Generator = require('yeoman-generator');
module.exports = class extends Generator {
//以下大部分内容将会写在里面
}; - 构造函数args是在命令行中直接传递的。 如:yo yzw-pc-web webapp,接受键值对的条件。
1
2
3
4
5
6
7constructor(args, opts) {
super(args, opts);
// args是在命令行中直接传递的。 如:yo yzw-pc-web webapp,接受键值对的条件。
this.log('args', args);
// opts和args很相似,但是opts是作为命令行标识使用的,如yo yzw-pc-web webapp --coffee。
this.log('opts', opts.coffee);
}
opts和args很相似,但是opts是作为命令行标识使用的,如yo yzw-pc-web webapp
运行
1 |
|
返回
1 |
|
初始化函数
1
2
3
4initializing() {
this.props = {}; //定义这个后面会用到
this.log('初始化完成');
}promoting块
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
44
45
46
47
48
49
50
51
52
53
54//promts是问题集合,在调用this.promt使其在运行yo的时候提出来
prompting() {
// Have Yeoman greet the user.
this.log(
yosay(`Welcome to the terrific ${chalk.red('generator-yzw-pc-web')} generator!`)
);
const prompts = [
{
type: 'confirm',
name: 'someAnswer',
message: 'Would you like to enable this option?',
default: true
}, {
type : 'input',
name : 'appname',
message : 'give Your project a name',
default : this.appname //appname是内置对象,代表工程名,这里就是上一级的目录名
}, {
type : 'confirm',
name : 'cool',
message : 'Would you like to enable the Cool feature?'
},
{
type: 'input',
name: 'projectDesc',
message: 'Please input project description:'
},
{
type: 'list',
name: 'projectLicense',
message: 'Please choose license:',
choices: ['MIT', 'ISC', 'Apache-2.0', 'AGPL-3.0']
},
{
type : 'input',
name : 'username',
message : 'What\'s your GitHub username', //里面的单引号需要转义
store : true
}
];
return this.prompt(prompts).then(props => {
// To access props later use this.props.someAnswer;
this.log('appname :', props.appname);
this.log('cool feature :', props.cool);
this.log('username :', props.username);
this.log('projectDesc :', props.projectDesc);
this.log('projectLicense :', props.projectLicense);
//最后将用户输入的数据存在this.props中,以方便后面调用。
this.props = props;
});
}default块
1
2
3
4
5
6
7
8
9
10
11
12defaults () { //判断工程名同名文件夹是否存在,不存在则自动创建
if (path.basename(this.destinationPath()) !== this.props.appname) {
this.log(
'Your generator must be inside a folder named ' + this.props.appname + '\n' +
'I\'ll automatically create this folder.'
);
//mkdirp是我们引用的模块,用来创建文件夹,此时没有设置项目根目录,则在当前目录创建
mkdirp(this.props.appname);
//this.destinationRoot则是设置要创建的工程的根目录为工程名文件夹。
this.destinationRoot(this.destinationPath(this.props.appname));
}
}writing
基于项目中generator/generator-yzw-pc-web/generators/app/templates来拷贝文件到项目工程中
generator的this.fs暴露出所有的文件方法,通过mem-fs-editor
1 |
|
- install
工程目录搭建的时候就会自动安装package.json里的依赖包1
2
3
4
5
6install() {
// 执行安装包,需要templates/package.json
this.installDependencies();
//使用npm安装依赖lodash
// this.npmInstall(['lodash'], { 'save-dev': true });
}
实际项目中使用脚手架
进入项目目录
1 |
|
执行
1 |
|
这里不包含前面的generator-
则会在projects目录下生成项目目录,你可以进入目录查看结果。