脚手架工具:前端工程化的发起者
脚手架的本质作用:
软件开发领域,脚手架是指通过各种工具来生成项目基础代码的技术。创建项目基础结构、提供项目规范和约定。
- 相同的组织结构
- 相同的开发范式
- 相同的模块依赖
- 相同的工具配置
- 相同的基础代码
- 例子:IDE创建项目的过程就是一个脚手架的工作流程
常用脚手架工具:
- React.js项目 -> create-react-app
- Vue.js项目 -> vue-cli
- Angular 项目 -> angular-cli
- Yeoman:可以通过yeoman自定义自己需要的脚手架工具
- Plop: 根据具体的模板生产相应的代码文件
Yeoman的使用
Yeoman是一款通用的脚手架系统,允许创建任何类型的应用程序,与语言无关。
Yeoman脚手架的使用
# 在全局范围安装yo$ npm install yo --global # or yarn global add yo# 安装对应的generator$ npm install generator-node --global # or yarn global add generator-node# 通过yo运行generator$ cd path/to/project-dir$ mkdir my-module$ yo node
sub-generator: 除了创建工程的脚手架,Yeoman还提供了sub-generator用于创建模块或组件,例如yo angular:controller MyNewController可以为项目添加新的controller
常规使用步骤
- 明确你的需求
- 找到合适的Generator
- 全局范围安装找到的Generator
- 通过Yo运行对应的Generator
- 通过命令行交互填写选项
- 生成你所需要的项目结构
自定义Generator
- Generator本质上(核心)就是一个NPM模块
- 项目名称必须以
generator-name的格式进行命名,generator-前缀必须有,后面name是生成器的名称 - 在
package.json中,除了项目名称必须为gererator-name的形式,keywords字段里面也必须包含yeoman-generator关键词。{"name": "generator-name","version": "0.1.0","description": "","files": ["generators"],"keywords": ["yeoman-generator"],"dependencies": {"yeoman-generator": "^1.0.0"}}
generator的基本项目结构

创建generator流程&示例
- 创建项目目录
mkdir generator-sample&cd generator-sample - 初始化项目
yarn initornpm init - 安装
yeoman-generatoryarn add yeoman-generatorornpm install yeoman-generator - 创建默认生成器目录
mkdir -p generators/app&touch generators/app/index.js,该文件将作为默认生成器的入口文件 - Yeoman提供了一个基础的Generator类,我们可以继承它实现自己的一些行为,每次调用生成器,被添加到类prototype中的方法也都会被当做任务,执行一次,通常是按顺序执行,某些特殊的方法可能会触发特定的顺序 ```javascript //generators/app/index.js const Generator = require(‘yeoman-generator’);
module.exports = class extends Generator { // 重写构造函数,构造函数中可能会运行一些特殊的方法,例如设置重要的状态控件,而它们无法再构造函数外部执行 constructor(args, opts) { super(args, opts); } sayHello() { // 在使用脚手架生成项目时会先打印hello world,prototype中的普通方法会依次按顺序执行 console.log(‘hello world’) } // 简单的写入文件操作 writing() { this.fs.write( this.destinationPath(‘temp.txt’), Math.random().toString() ) } }
6. 创建Npm包链接`yarn link` or `npm link`7. 使用`yo sample`即可创建项目,生成temp.txt文件。<a name="52d6cc30"></a>#### 不会被当做任务的方法- **私有方法不会被当做任务:** 上面提到能被`Object.getPrototypeOf(Generator)`获取到的方法都是generator的任务,其中有个特例为私有方法`以_开头的方法`不会被当做任务```javascript// yeoman官方给出的示例代码class extends Generator {// 会被当做任务自动执行method1() {console.log('hey 1');}// 不会被当做任务自动执行_private_method() {console.log('private hey');}}
实例方法不会被当做任务执行:
// yeoman官方给出的示例代码class extends Generator {constructor(args, opts) {// Calling the super constructor is important so our generator is correctly set upsuper(args, opts)// 实例方法不会被当做任务执行this.helperMethod = function () {console.log('won\'t be called automatically');};}}
继承自父Generator的方法不会被当做任务:
// yeoman官方给出的示例代码class MyBase extends Generator {helper() {console.log('methods on the parent generator won\'t be called automatically');}}module.exports = class extends MyBase {// exec不会被当做任务自动执行exec() {this.helper();}};
plop的使用
一个小而美的脚手架工具
- 将plop模块作为项目开发依赖安装
- 在项目根目录下创建一个plopfile.js文件
- 在plofile.fs文件中定义脚手架任务
- 编写用于生成特定类型文件的模板
- 通过plop提供的CLI运行脚手架任务
node cli应用
脚手架本身就是一个node的cli应用,我们可以通过node cli应用来实现自己的脚手架。通过以上对Yeoman与Plop.js的介绍,我们可以发现它们在实现时都使用了 inquirer.js 与用户进行交互。使用node cli应用实现脚手架,我们可以选择inquirer.js结合结合commander.js,并搭配各种小工具例如chalk.js, log-symbols等小工具自定义一些输出信息。node cli应用的核心就是在
package.json中添加一个"bin"字段,指向js cli脚本,js脚本的书写方式必须由以下代码开头,其他代码则为正常的js代码
#!/usr/bin/env nodeconsole.log('hello')
通过node实现脚手架的方案
- 创建一个项目
xxx-cli,yarn init初始化项目 添加
bin/cli.js文件,并填写如下代码#!/usr/bin/env nodeconsole.log('hello world')
在
package.json中添加bin字段{"name": "node-cli","version": "1.0.0","main": "index.js","bin": {"node-cli": "./bin/cli.js"},"license": "MIT","dependencies": {"ejs": "^3.1.5","inquirer": "^7.3.3"}}
在项目根目录通过
npm link或者yarn link创建全局软连接- 如果在mac或linux下编写代码还需要给cli脚本添加执行权限
chmod 755 ./bin/cli.js - 然后随便进入一个目录,执行
node-cli,注意你自己在bin字段下填写的key是什么,命令就是什么,这里是node-cli,然后输出hello world
至此使用node实现了cli的应用,脚手架所需的基本知识已经具备。
除此之外,脚手架本质上就是通过cli与用户进行各种交互,收集回答后根据用户回答选择性地创建项目模板。所以再结合 inquirer.js 或commander.js 可以进行与用户的交互,并收集回答。
结合 ejs template syntax 等模板方案,根据收集的回答,为用户生成相应的基础代码。
