使用 Yeoman 定制自己的项目脚手架

2,269 阅读5分钟

一、Yeoman 是什么

1、 Yeoman能帮助你创建一个新的项目工程, 提供最佳实践和工具,以帮助你保持高效率的编码,为此,他们提供了一个构建的生态系统, 生成器 generator是一个插件, 可以使用yo命令来构建完整的项目或者项目的一部分

2、 通过官方的生成器,他们建立了一个Yeoman的工作流,这个流是由一个强大且固定的客户端组建,它包含工具和框架,可以帮助开发者快速构架漂亮的web应用程序,Yeoman提供了负责开始项目开发的一切,没有任何让人头痛的手动配置 3、

二、应用场景

假设现在有这样的开发场景: 公司开发团队,是基于特定的技术栈已经完成了项目A的开发和上线等工作,项目A的技术栈 React + Redux-thunk + axios + styled-components + Ant Design 现在团队需要开展一个新的项目B, 在技术评审的过程中需要在项目A技术上在添加TypeScript, 其他的保持不变, 这个时候会发现,项目A和项目B的基本结构都是一致的。那么我们在开展项目B的时候, 有两种方式

1、从0开始创建目录接口, 重新配置打包环境,安装依赖等,

2、从原来项目A 复制一份固定的目录结构和文件。对不同的文件进行修改

缺点:

  • 重复了大量的重复性工作。费时费力
  • 修改的文件很多,一不小心容易遗漏,甚至出错

那么能不能自己写一个项目的模板, 还可以支持私人定制呢?根据自己的需要定制。 答案是可以的, 这里使用第三个方案

3 、使用Yeoman脚手架工具 在初始化项目B的时候,我们只需在终端输入, 在使用交互方式简单配置某些值, 类似初始化vue-cli,初始化项目的时候不需要在进行琐碎重复的工作, Yeoman帮助我们快速开始构建项目

三、准备工作

  • node环境
  • npm 或 yarn

四、通过 Yeoman 初始化项目

开源社区有非常多的项目目录模板, 这里以webapp为例

1、全局安装 yo

yarn global add yo
yarn global generator-generator

2、找到对应的generator

Yeoman会根据对应 generator 帮助我们生成对应的项目结构以及自动安装依赖

yarn global add generator-webapp

通过 yo 命令来创建项目,这里可以根据我们自己的需要选择所需要的依赖进行安装,之后我们就可以得到一个web应用的基础结构

yo webapp

五、自定义Generator (基于Yeomen构建自己的脚手架)

脚手架所做的事情:

  • 接收用户输入
  • 根据用户输入生成模板文件
  • 将模板文件拷贝到目标目录(通常是用户运行脚手架的目录)
  • 安装依赖

Generator基本结构

|- generators/ ............................................ 生成器目录
|  |_ app /    ............................................ 默认生成器目录
|     | index.js .......................................... 默认生成器实现
|_ package.json ........................................... 模块吧配置文件

创建文件夹

generator-vue-project
  • 执行 yarn init
  • 安装 Yeoman 依赖 yarn add yeoman-generator
  • 接下来我们在项目根目录创建以下文件 generators/app/index.js

六、编写模板代码

在 generators/app/index.js 文件下

const Generator = require('yeomen-generator')
module.exports = class extends Generator {
    // 接受用户输入
    promping () { 
        return this.prompt([
            {
                type: 'input', // type 非必填, 默认是text, 即让用户输入文本
                name: 'name', // name 用户输入项的标识,在获取用户输入值的时候会用到
                message: 'Your project name', // message是给用户的提示信息
                default: this.appname // 用户输入默认值,非必填
            }
        ])
        .then(answers => { // 拿到用户输入的数据
            this.answers = answers
        })
    }
    writing () {
        // 把每一个文件都通过模板转换到目标路径
        const templates = [
            '.browserslistrc',
            '.eslintrc.js',
            '.gitignore',
            'babel.config.js',
            'package.json',
            'README.md',
            'yarn.lock',
            'public/favicon.ico',
            'public/index.html',
            'src/App.vue',
            'src/main.js',
            'src/store/index.js',
            'src/views/About.vue',
            'src/views/Home.vue',
            'src/router/index.js',
            'src/components/HelloWorld.vue',
            'src/assets/logo.png',
            'src/tests/unit/example.spec.js'
        ]
        templates.forEach(item => {
            // 遍历每个文件路径 item
            this.fs.copyTpl(
                this.templatePath(item),
                this.destinationPath(item),
                this.answers
            )
        })
    }
}
  • 将模板文件放入 gennerator/app/templates 中,这个是生成新的项目结构的原材料

  • 执行 yarn link 创建全局模块并将其符号链接到本地模块

  • 创建新的文件夹,执行 yo vue-project vue-project就是我们自定义的Generator (生成器)

  • 在templates文件中可以使用EJS模板语法,把模板和用户输入的信息结合,就会生成一个新的项目文件 我们需要在package.json REMADMEindex.html 中描述项目名替换成 <%= name %>, 之后我们就可以得到一个基于Yemoman构建的一个vue项目目录结构

cd  my-vue-project
yo vue-project
赋值 <%= name %>
表达式 <% if(someAnswer){ xxx } %>

{ "name": "<%= name %>" }

八、发布Generator

  • Generator实际上就是一个npm模块, 所以说我们如果要去发布Genertor其实就是去发布npm模块
  • 准备一个npm账号
  • 执行yarn publish
  • 如果淘宝镜像源的问题 执行yarn publish --registry=https://registry.yarnpkg.com 因为淘宝镜像源是只读的

九、Yeoman生命周期

  • initializing - 初始化函数
  • prompting - 接收用户输入阶段
  • configguring - 编辑和配置项目的配置文件
  • default - 自定义功能函数名称
  • writing - 生成项目目录结构阶段
  • conflicts - 统一处理冲突, 如也要生成的文件已经存在是否覆盖等处理
  • install - 安装依赖
  • end - 生成器结束阶段, clean工作

十、Yeoman 组装流程

  • 交互式配置 generators/app/index.js 通过命令行交互询问用户问题或直接输入配置信息来完成模板传参
  • 写入文件 这个过程会把模板文件复制到指定的目录中。主要通过 writing() fs.copyTpl 两个函数来执行具体的操作
  • 安装项目的依赖

参考

Yeoman官方文档

用 yeoman 打造自己的项目脚手架

本文使用 mdnice 排版