使用Yeoman 实现自己的脚手架工具


theme: smartblue

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

介绍与演示

yeoman是一个通用脚手架,可以用来定义自己的脚手架工具

核心原理:

yo + 不同的生成器 = 不同的项目

快速使用一个生成器搭建项目

注:我们以生成一个eslint插件开发模板为例!!!!!!!!!!!!

首先需要进行环境确认(必须具备node环境)

node -v
npm -v

更改镜像源为国内镜像(保证依赖下载速度更快)

npm config set registry https://registry.npmmirror.com

tip:可通过 npm config get registry 查看镜像源*

全局安装 yo命令

npm i yo -g

全局安装对应的生成器 generator

npm i generator-eslint -g

生成器的格式是generator-名称

创建项目,进入目录

mkdir yeoman-eslint
cd yeoman-eslint

通过yo运行对应的generator

yo eslint

使用时可以省略generator-

自定义一个生成器 mystudy

项目搭建

1、生成器本身也是一个项目,需要创建

mkdir generator-mystudy
cd generator-mystudy
npm init -y

注:生成器的项目名称必须是 generator- 开头

2、项目中安装基类

npm i yeoman-generator -S

这个插件内封装了很多方法,一会儿开发,我们会使用这个插件.

3、编辑入口文件

generator-mystudy/generators/app/index.js

因为我们可以创建多个生成器,所以文件命名为generators

先不用管为什么入口文件要这么创建,这是官方提供的规范,我们稍后会详细讲解。我们先体验这个过程。

开发mystudy生成器

在学习以下内容前,请先强化js类的学习!!

在入口文件先简单写一句代码

// 引入生成器的父类
const Generator = require("yeoman-generator");
// 导出继承的子类
module.exports = class extends Generator {
  // 子类被new时,test方法会自动执行
  test(){
    // 这里没有使用console.log();方法,而是直接使用了父类封装的log方法,因为console在某些情况可能出错
    this.log("我的第一");
  }
};

现在,一个简单的生成器就完成了,理论上我们可以在本地直接使用 npm i generator-mystudy -g , 不过,我们首先需要将generator-mystudy这个目录让npm 可以全局访问到才行。

查看npm 全局安装的根目录

npm root -g

为了便于观察我们的目录是否被设置成了全局目录,可以先打开npm根目录

在窗口打开这个文件夹

start D:\Program\node\node_modules

将项目链接到npm根目录(全局访问项目)

npm link

执行命令后,可以发现 目录里的快捷方式已经创建好了,现在就可以全局访问项目了。

image.png
试试我们的生成器

yo mystudy

tip:可以省略 generator-

现在,打开控制台,可以看到生成器里面的内容被打印了。我们的生成器已经正常运行了,摸摸哒!

完善mystudy生成器

思路:

  1. 询问,获取信息
  2. 生成预定义的项目结构
  3. 安装依赖

首先,我们需要了解Generator的构造方法,询问,渲染模板及安装依赖等功能。

下面的函数名称等,我们都采用了官方api,本文以体验为主,您可以在下一篇文章了解具体用法。

用户交互

用户交互通过prompting方法完成,这是一个官方api

这里的交互过程引用了requirejs的内容,因此,具体使用方法我们可以参考requireJs

// 引入生成器的父类
const Generator = require("yeoman-generator");
// 导出继承的子类
module.exports = class extends Generator {
  // 构造方法可以处理自定义的命令行参数
  constructor(args, opts) {
    super(args, opts);
  }
  // 1.询问,获取信息
  prompting() {
    // prompt方法返回一个promise,用于询问用户信息,并返回一个结果对象
    return this.prompt([
      {
        // 问题类型,需要用户输入
        type: "input",
        // 信息储存的字段
        name: "projectName",
        // 提示信息
        message: "请输入项目名称:",
        // 默认值 this.appname默认是项目的文件名
        default: this.appname,
      },
      {
        type: "input",
        name: "username",
        message: "请输入您的名称:",
        default: "",
      },
    ]).then((answers) => {
      this.log(answers);
    });
  }
  // 2.生成预定义的项目结构
  // 3.安装依赖
};

此时,我们在命令行执行 yo mystudy 就会执行这些询问信息,并返回了我们需要的信息对象

image.png

生成项目结构

生成目录结构采用writing官方api,生成项目结构(根据模板生成我们的项目)使用了this.sourceRoot()this.destinationRoot()this.fs.copyTpl等方法。

// 引入生成器的父类
const Generator = require("yeoman-generator");
// 导出继承的子类
module.exports = class extends Generator {
  // 构造方法可以处理自定义的命令行参数
  constructor(args, opts) {
    super(args, opts);
  }
  // 1.询问,获取信息
  prompting() {
    .....
  }
  // 2.生成预定义的项目结构
  writing() {
    // 获取模板目录
    let srcDir = this.sourceRoot();
    // 获取目标目录(在哪里执行命令就是哪里)
    let destDir = this.destinationRoot();
    // 将目标目录内容生成到模板目录内
    this.fs.copyTpl(srcDir, destDir,this.answers);
  }
  // 3.安装依赖
};

安装依赖

如果您想在生成项目的时候自动安装依赖,执行install方法即可。

// 引入生成器的父类
const Generator = require("yeoman-generator");
// 导出继承的子类
module.exports = class extends Generator {
  // 构造方法可以处理自定义的命令行参数
  constructor(args, opts) {
    super(args, opts);
  }
  // 1.询问,获取信息
  prompting() {
    .....
  }
  // 2.生成预定义的项目结构
  writing() {
   ....
  }
  // 3.安装依赖
  install() {
    this.env.options.nodePackageManager = "npm"
    console.log('this.env.options: ', this.env.options);
  }

  end(){
    this.log("项目创建成功")
  }
};

至此,一个基础的自定义生成器就具备雏形了。

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容