一、什么是脚手架
在公司的各个项目中往往拥有相同的组织结构、相同的开发范式、相同的模块依赖、相同的工具配置、相同的基础代码。而脚手架的可以帮我们快速的创建项目基础结构,提供项目规范和约定
二、准备工作
安装verdaccio和nrm,verdaccio用于搭建私有npm服务器,nrm是npm源管理器
1、verdaccio:
全局安装:npm install -g verdaccio
运行:直接输入verdaccio命令即可运行
TIPS:可以根据自己的需要修改配置文件
2、nrm:
全局安装:npm install -g nrm
常用命令:
- nrm ls:查看npm源
- nrm current:查看当前源
-
nrm use <registry>切换npm源,registry为源名
- nrm add <registry> <url>:添加源,registry为源名,url为源地址
- nrm del <registry>:删除源
三、Yeoman
1、什么是yeoman
相比于其他脚手架而言,yeoman更像是一个脚手架平台,它配合各种generator可以构建不同的项目,因此我们可以通过创建自己的generator来创建脚手架
2、yeoman的使用步骤
- 全局安装yeoman:npm install -g yo
- 全局安装对应的generator:如:npm install -g generator-xxxxx
- 使用yo命令运行generator构建项目:yo xxxxx
- 通过命令行交互填写选项
- 根据填写的选项生成所需的项目结构
TIPS:generator的包名必须以 generator- 开头,使用yo运行generator时,需要去掉generator-前缀
3、开发自己的generator
generator本质就是一个npm模块,它必须遵循一定的项目结构
3.1、规则:
- 文件夹必须命名为 generator-<name> 的形式
- 项目中须有 package.json 文件,且属性值须满足下列要求:
- name 属性值须是 "generator-<name>"
- keywords 属性值必须为 "yeoman-generator"
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也内置了一些的预先定义好执行顺序的方法供我们使用(类似生命周期方法)。
- initializing -- 初始化方法(检查状态、获取配置等)
- prompting -- 获取用户交互数据
- configuring -- 编辑和配置项目的配置文件
- default -- 如果generator内部还有不符合任意一个任务队列任务名的方法,将会被放在default这个任务下进行运行
- writing -- 填充预置模板
- conflicts -- 处理冲突(仅限内部使用)
- install -- 进行依赖的安装(eg:npm,bower)
- end -- 最后调用,做一些clean工作
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代理到全局
四、发布generator模块
使用npm publish命令发布generator