脚手架工具:前端工程化的发起者

脚手架的本质作用:

软件开发领域,脚手架是指通过各种工具来生成项目基础代码的技术。创建项目基础结构、提供项目规范和约定。

  • 相同的组织结构
  • 相同的开发范式
  • 相同的模块依赖
  • 相同的工具配置
  • 相同的基础代码
  • 例子:IDE创建项目的过程就是一个脚手架的工作流程

常用脚手架工具:

  • React.js项目 -> create-react-app
  • Vue.js项目 -> vue-cli
  • Angular 项目 -> angular-cli
  • Yeoman:可以通过yeoman自定义自己需要的脚手架工具
  • Plop: 根据具体的模板生产相应的代码文件

Yeoman的使用

Yeoman是一款通用的脚手架系统,允许创建任何类型的应用程序,与语言无关。

Yeoman脚手架的使用

  1. # 在全局范围安装yo
  2. $ npm install yo --global # or yarn global add yo
  3. # 安装对应的generator
  4. $ npm install generator-node --global # or yarn global add generator-node
  5. # 通过yo运行generator
  6. $ cd path/to/project-dir
  7. $ mkdir my-module
  8. $ yo node

sub-generator: 除了创建工程的脚手架,Yeoman还提供了sub-generator用于创建模块或组件,例如yo angular:controller MyNewController可以为项目添加新的controller

常规使用步骤

  1. 明确你的需求
  2. 找到合适的Generator
  3. 全局范围安装找到的Generator
  4. 通过Yo运行对应的Generator
  5. 通过命令行交互填写选项
  6. 生成你所需要的项目结构

自定义Generator

  • Generator本质上(核心)就是一个NPM模块
  • 项目名称必须以generator-name的格式进行命名,generator-前缀必须有,后面name是生成器的名称
  • package.json中,除了项目名称必须为gererator-name的形式,keywords字段里面也必须包含yeoman-generator关键词。
    1. {
    2. "name": "generator-name",
    3. "version": "0.1.0",
    4. "description": "",
    5. "files": [
    6. "generators"
    7. ],
    8. "keywords": ["yeoman-generator"],
    9. "dependencies": {
    10. "yeoman-generator": "^1.0.0"
    11. }
    12. }

generator的基本项目结构

前端工程化-脚手架 - 图1

创建generator流程&示例

  1. 创建项目目录mkdir generator-sample & cd generator-sample
  2. 初始化项目yarn init or npm init
  3. 安装yeoman-generator yarn add yeoman-generator or npm install yeoman-generator
  4. 创建默认生成器目录mkdir -p generators/app & touch generators/app/index.js,该文件将作为默认生成器的入口文件
  5. 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() ) } }

  1. 6. 创建Npm包链接`yarn link` or `npm link`
  2. 7. 使用`yo sample`即可创建项目,生成temp.txt文件。
  3. <a name="52d6cc30"></a>
  4. #### 不会被当做任务的方法
  5. - **私有方法不会被当做任务:** 上面提到能被`Object.getPrototypeOf(Generator)`获取到的方法都是generator的任务,其中有个特例为私有方法`以_开头的方法`不会被当做任务
  6. ```javascript
  7. // yeoman官方给出的示例代码
  8. class extends Generator {
  9. // 会被当做任务自动执行
  10. method1() {
  11. console.log('hey 1');
  12. }
  13. // 不会被当做任务自动执行
  14. _private_method() {
  15. console.log('private hey');
  16. }
  17. }
  • 实例方法不会被当做任务执行:

    1. // yeoman官方给出的示例代码
    2. class extends Generator {
    3. constructor(args, opts) {
    4. // Calling the super constructor is important so our generator is correctly set up
    5. super(args, opts)
    6. // 实例方法不会被当做任务执行
    7. this.helperMethod = function () {
    8. console.log('won\'t be called automatically');
    9. };
    10. }
    11. }
  • 继承自父Generator的方法不会被当做任务:

    1. // yeoman官方给出的示例代码
    2. class MyBase extends Generator {
    3. helper() {
    4. console.log('methods on the parent generator won\'t be called automatically');
    5. }
    6. }
    7. module.exports = class extends MyBase {
    8. // exec不会被当做任务自动执行
    9. exec() {
    10. this.helper();
    11. }
    12. };

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代码

  1. #!/usr/bin/env node
  2. console.log('hello')

通过node实现脚手架的方案

  • 创建一个项目xxx-cliyarn init初始化项目
  • 添加bin/cli.js文件,并填写如下代码

    1. #!/usr/bin/env node
    2. console.log('hello world')
  • package.json中添加bin字段

    1. {
    2. "name": "node-cli",
    3. "version": "1.0.0",
    4. "main": "index.js",
    5. "bin": {
    6. "node-cli": "./bin/cli.js"
    7. },
    8. "license": "MIT",
    9. "dependencies": {
    10. "ejs": "^3.1.5",
    11. "inquirer": "^7.3.3"
    12. }
    13. }
  • 在项目根目录通过npm link或者yarn link创建全局软连接

  • 如果在mac或linux下编写代码还需要给cli脚本添加执行权限chmod 755 ./bin/cli.js
  • 然后随便进入一个目录,执行node-cli,注意你自己在bin字段下填写的key是什么,命令就是什么,这里是node-cli,然后输出hello world

至此使用node实现了cli的应用,脚手架所需的基本知识已经具备。

除此之外,脚手架本质上就是通过cli与用户进行各种交互,收集回答后根据用户回答选择性地创建项目模板。所以再结合 inquirer.jscommander.js 可以进行与用户的交互,并收集回答。

结合 ejs template syntax 等模板方案,根据收集的回答,为用户生成相应的基础代码。