前言
为了寻找最适合自己的脚手架,解放双手,做到真正的傻瓜式一键搭建基础开发框架。
初识Yeoman
Yeoman 是什么?干什么的?能解决我们日常开发的什么痛点?
如下是官方的描述:
Yeoman is a generic scaffolding system allowing the creation of any kind of app. It allows for rapidly getting started on new projects and streamlines the maintenance of existing projects.
根据 Yeoman 官网 yeoman.io/ 的介绍,我们可以知道 yeoman 是一个通用型的脚手架工具,相较于 vue-cli 和 create-react-app 等脚手架来说,它提供的是更加基础的东西,我们能更好的根据实际业务来扩展和搭建属于自己的脚手架。
基础配置和搭建
1. 安装 Yeoman
首先我们需要先全局安装 Yeoman
npm install -g yo
2. 新建脚手架文件夹
然后我们需要新建文件夹,并且初始化 npm。
不过我们需要注意 Yeoman 的脚手架必须是以 generator- 开头的,例如:我们的脚手架叫 name ,那么脚手架项目名就必须是 generator-name。
// 新建文件夹,此时脚手架名为(basic-template)
mkdir generator-basic-template
cd generator-basic-template
// 初始化 npm
npm init
3. 默认的目录结构
Yeoman 必须遵循官方规定的目录结构来进行开发。官方描述如下:
Yeoman’s functionality is dependent on how you structure your directory tree. Each sub-generator is contained within its own folder.
The default generator used when you call yo name is the app generator. This must be contained within the app/ directory.
Sub-generators, used when you call yo name:subcommand, are stored in folders named exactly like the sub command.
意思是说根目录下必须有 generators 文件夹,generators 文件夹下面必须要有 app 文件夹,然后 app 文件夹下面才是我们编译脚手架的主入口文件 index.js,templates(你可以将你想要的目录结构和通用文件放到此处)为模板文件夹。
目录结构如下:
├───package.json
└───generators/
├───app/
| ├───templates
│ └───index.js
└───router/
└───index.js
其中 router 目录表示的是 sub-generator
使用命名分别为 yo basic-template 和 yo basic-template:router。
当然你可以可以使用下面的目录结构:
├───package.json
├───app/
| ├───templates
│ └───index.js
└───router/
└───index.js
这两种目录结构的区别主要是 package.json 文件中 files 字段的引入不一样:
1)默认的 package.json
{
...
"files": ["generators"]
...
}
2)非默认 package.json
...
"files": [
"app",
"router"
]
...
4. package.json 文件
我们需要对 package.json 文件做适当的修改
// package.json
{
"name": "generator-basic-template",
"version": "1.0.0",
"description": "This is a scaffold template",
"main": "index.js",
"files": [
"generators"
],
"keywords": [
"yeoman-generator"
],
"scripts": {},
"author": "",
"license": "ISC",
"dependencies": {
"yeoman-generator": "^4.0.0"
}
}
其中 files 和 keywords 都是默认的。
进入正题
目标文件:generator -> app -> index.js
安装 yeoman-generator
npm install --save yeoman-generator
index.js 的编写
// 引入 yeoman-generator
const Generator = require('yeoman-generator')
// 继承 Generator 并且导出
module.exports = class extends Generator {
constructor (args, opts) {
super(args, opts)
}
// 初始化
// Your initialization methods (checking current project state, getting configs, etc)
initializing () {
this.log('initializing')
}
// 接收用户输入(在命令行中发出询问)
// Where you prompt users for options (where you’d call this.prompt())
prompting () {
// Yeoman 在询问环节会自动调用该方法
// 此方法中可以调用父类的 prompt 方法来向用户发出询问
// prompt 返回的是一个 Promise 方法
// prompt 接收一个数组,数组中每个元素就是一个问题
this.log('prompting')
return this.prompt([
{
type: 'input',
name: 'name',
message: 'Your project?',
default: this.appname
}
]).then(answers => {
// 获取用户输入的问答上下文
this.answers = answers
this.log(answers)
})
}
// 配置
// Saving configurations and configure the project
// (creating .editorconfig files and other metadata files)
configuring () {
// 创建配置相关的文件
this.log('configuring')
}
// 默认执行
// If the method name doesn’t match a priority, it will be pushed to this group.
default () {
// 如果方法名没有匹配到,则会进入到这个方法中
this.log('default')
}
// 写入函数(模板生成的方法)
// Where you write the generator specific files (routes, controllers, etc)
writing () {
// Yeoman 自动生成文件时会调用该方法
// 模板目录在该方法中生成写入
this.log('writing')
const ctx = this.answers
const tmpl = this.templatePath('foo.txt')
const output = this.destinationPath('foo.txt')
this.fs.copyTpl(tmpl, output, ctx)
}
// 处理冲突
// Where conflicts are handled (used internally)
conflicts () {
this.log('conflicts')
}
// 安装依赖的地方
// Where installations are run (npm, bower)
install () {
this.log('install')
// 安装依赖
// this.npmInstall()
}
// 结尾的地方
// Called last, cleanup, say good bye, etc
end () {
this.log('⚡完成')
}
// // 处理异步的情况
// asyncTask () {
// const done = this.async()
// setTimeout(() => {
// done()
// }, 1000)
// }
}
执行生命周期:
initializing初始化,一般可以进行获取项目状态、配置等操作。prompting接收用户输入(在命令行中发出询问)。configuring保存配置并配置项目(创建.editorconfig文件和其他元数据文件)default如果方法名称与优先级不匹配,它将进入到该方法中。writing模板目录在该方法中生成写入conflicts处理冲突的位置(内部使用)install安装依赖end结束
将脚手架安装到全局
编写好的脚手架需要使用 npm link 安装到全局,只有这样我们才能在全局使用。
例如: 我们创建了 A 目录,然后进入到 A 目录,然后在命令行中使用 yo basic-template 即可快速搭建我们的目录结构了。
当然,你可以将你的脚手架发布的 npm 或者是 Yeoman 的仓库中。这样后续你就可以直接使用 npm 安装,然后直接使用就可以了。
总结
- 全局安装
Yeoman - 创建目录并初始化
- 编写
index.js - 安装到全局
npm link - 使用
yo basic-template最终目录结构:
├───package.json
└───generators/
├───app/
| ├───templates
| | └───foo.txt
│ └───index.js
└───router/
└───index.js