在公司的各个项目中往往拥有相同的组织结构、相同的开发范式、相同的模块依赖、相同的工具配置、相同的基础代码。而脚手架的可以帮我们快速的创建项目基础结构,提供项目规范和约定
安装verdaccio和nrm,verdaccio用于搭建私有npm服务器,nrm是npm源管理器
全局安装:npm install -g verdaccio
运行:直接输入verdaccio命令即可运行
TIPS:可以根据自己的需要修改配置文件
全局安装:npm install -g nrm
常用命令:
nrm use
相比于其他脚手架而言,yeoman更像是一个脚手架平台,它配合各种generator可以构建不同的项目,因此我们可以通过创建自己的generator来创建脚手架
TIPS:generator的包名必须以 generator- 开头,使用yo运行generator时,需要去掉generator-前缀
generator本质就是一个npm模块,它必须遵循一定的项目结构
3.1、规则:
3.2、配置package.json
{ |
3.3、安装yeoman-generator依赖
npm install --save yeoman-generator
3.4、目录结构
yeoman 的功能强依赖于文件结构,每一个 sub-generator 都有自己的结构。
yeoman 支持如下两种定义目录结构的方式:
模式一:
模式二:
如果使用的是第二种方式,需要在package.json中显式声明
{ |
可以运行yo [generator name]命令执行,默认会执行app目录下的 generator;
yeoman还支持sub-generator的概念,运行yo [generator name]:subcommand执行,这要求项目中必须存在名为subcommand的与app同名的文件夹。
例如,上述结构中的router目录就是一个sub-generator,可以运行命令yo [generator name]:router执行。
每个generator下必须包含index.js文件,为generator的入口文件
3.5、Generator实现
yeoman提供了一个Generator基类,方便我们实现自己的功能。
对于我们自定义的方法,yeoman将按照队列顺序依次执行,同时yeoman也内置了一些的预先定义好执行顺序的方法供我们使用(类似生命周期方法)。
3.6、交互
prompts是yeoman实现交互的主要方式,可以在prompting方法中调用this.prompt()方法实现与用户的交互,它是基于inquirer.js实现,交互方式主要有input、list、confirm
const Generator = require('yeoman-generator'); module.exports = class extends Generator { constructor(args, opts) { super(args, opts); } //获取用户交互数据 prompting() { const prompts = [ { type: 'input', name: 'name', message: 'Project name:', default: 'test-project' }, { type: 'list', name: 'framework', message: 'choose a framework', choices: ['React', 'Vue', 'Angular'], default: 'React' } ]; //this.prompt()是个异步函数,在then方法里获取用户输入的值 this.prompt(prompts).then(answers => { this.name = answers.name; this.framework = answers.framework; }) } }; |
3.6、根据模板生成脚手架
获取到了交互数据,接下来就该根据预定义的模板去生成脚手架了。
这一步本质上是文件的拷贝,所以需要考虑的有三个问题
这些yeoman
已经帮我们完成了封装。
读取源文件地址:
模板路径顾名思义就是模板存放的路径,默认存在当前路径下的templates
目录,可以调用this.sourceRoot()
来获取,也可以指定路径。
class extends Generator { |
读取目标地址:
目标目录即我们要生成脚手架的目录,在yeoman
中定义了两个目标目录的位置,当前工作目录和最相邻的一个包含.yo-rc.json
文件的父级目录。
.yo-rc.json文件允许用户在子目录下运行yeoman命令去操作工程,这样保证了用户操作的连贯性。
yeoman提供了this.destinationRoot()方法供我们获取目标路径。
调用时可以指定子目录
class extends Generator { |
拷贝文件:
yeoman提供了copyTpl方法来完成模板的拷贝,copyTpl方法在this.fs下且默认使用ejs语法。
class extends Generator { |
TIPS:在开发阶段可以使用npm link将generator代理到全局
使用npm publish命令发布generator