前端自动化工具plop-js

665 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情

前言

平常大家开发每个页面骨架大致相似,每次开发新页面都要一步一步的配置,相当繁琐。有了Plop,就可以实现自动化了,Plop 旨在根据模板文件自动化创建组件,接下来我就来介绍一下Plop如何帮助我们在开发过程中提高工作效率。

安装

可参考 github.com/plopjs/plop

npm install --save-dev plop
//或
yarn add -D plop

#当然你也可以把它全局安装
npm install -g plop

然后在项目的根目录创建一个plopfile.js

module.exports = function (plop) {};

快速上手

配置

大致涉及这些文件:


├── plop-templates        # templates模板
│   ├── cpv               # cpv
│        ├── index.hbs    # 模板定义
│        └── prompt.js    # 配置
│   ├── view              # view
│   ├── component         # component
│   ├── store             # store
│   └── utils.js          # utils
├── plopfile.js           # plopfile配置
├── package.json
└── yarn.lock
//plopfile.js
const cpvGenerator = require('./plop-templates/cpv/prompt');
const viewGenerator = require('./plop-templates/view/prompt');
const componentGenerator = require('./plop-templates/component/prompt');
const storeGenerator = require('./plop-templates/store/prompt.js');

module.exports = function(plop) {
  plop.setGenerator('cpv', cpvGenerator);
  plop.setGenerator('view', viewGenerator);
  plop.setGenerator('component', componentGenerator);
  plop.setGenerator('store', storeGenerator);
};

先来一个简单点的配置

//plop-templates/view/index.hbs
{{#if template}}
<template>
  <div class="{{ properCase name }}"></div>
</template>
{{/if}}

{{#if script}}
<script>
  export default {
    name: '{{ properCase name }}',
    props: {},
    data() {
      return {}
    },
    created() { },
    mounted() { },
    methods: {}
  }
</script>
{{/if}}

{{#if style}}
<style lang="less" scoped>

</style>
{{/if}}
//plop-templates/view/prompt.js
const { notEmpty } = require('../utils.js');

module.exports = {
  description: 'generate a view',
  prompts: [
    {
      type: 'input',
      name: 'name',
      message: 'view name please',
      validate: notEmpty('name')
    },
    {
      type: 'checkbox',
      name: 'blocks',
      message: 'Blocks:',
      choices: [
        {
          name: '<template>',
          value: 'template',
          checked: true
        },
        {
          name: '<script>',
          value: 'script',
          checked: true
        },
        {
          name: 'style',
          value: 'style',
          checked: true
        }
      ],
      validate(value) {
        if (value.indexOf('script') === -1 && value.indexOf('template') === -1) {
          return 'View require at least a <script> or <template> tag.';
        }
        return true;
      }
    }
  ],
  actions: data => {
    const name = '{{name}}';
    const actions = [
      {
        type: 'add',
        path: `src/view/${name}/index.vue`,
        templateFile: 'plop-templates/view/index.hbs',
        data: {
          name: name,
          template: data.blocks.includes('template'),
          script: data.blocks.includes('script'),
          style: data.blocks.includes('style')
        }
      }
    ];

    return actions;
  }
};

//plop-templates/utils.js
exports.notEmpty = name => v =>
  !v || v.trim() === '' ? `${name} is required` : true
//package.json
{
    "scripts": {
        "new": "plop",
  },
}

运行

yarn new

20201129170600.png

20201129170727.png

20201129170821.png

20201129170821.png

20201129170920.png

这样即可创建完成了。

使用

plop命令相关主要借助promptInquirer

prompt 主要是命令行输入表单控件,它的相关功能:

  • 提示用户输入
  • 支持默认值和字段
  • 验证
  • 各种提示
//表单
var schema = {
    properties: {
      name: {
        pattern: /^[a-zA-Z\s\-]+$/,
        message: 'Name must be only letters, spaces, or dashes',
        required: true
      },
      password: {
        hidden: true
      }
    }
};
//
prompt.start();

//获取用户名,密码
prompt.get(schema, function (err, result) {
    console.log('Command-line input received:');
    console.log('  name: ' + result.name);
    console.log('  password: ' + result.password);
});
//这是可用于验证和提示控件的属性的概述:
  {
    description: 'Enter your password',     // 描述
    type: 'string',                 // 类型
    pattern: /^\w+$/,                  // 正则
    message: 'Password must be letters', //警告提示
    hidden: true,                        // 如果为true,则不展示
    replace: '*',                        // 替换
    default: 'lamepassword',             // 默认
    required: true                        // 是否必填
    before: function(value) { return 'v' + value; } //回调执行前,执行
  }

Inquirer 交互式命令行工具 相关功能:

  • 提供错误回调
  • 询问操作者问题
  • 获取并解析用户输入
  • 检测用户回答是否合法
  • 管理多层级的提示
参数含义
type类型 相关值有:input,number,confirm, list,rawlist,expand,checkbox,password,editor
name存储当前字段的变量
message问题的描述
default默认值
choices列表选项
validate验证
filter过滤
transformer对用户回答的显示效果进行处理
when根据前面问题的回答,判断当前问题是否需要被回答
pageSize渲染行数
prefix修改 message 默认前缀
suffix修改 message 默认后缀
askAnswered如果答案已经存在,则强制提示该问题。
loop启用列表循环。默认值:true

有了这些配置,我们就可以定义自己的模板了。

最后贴一下部分配置代码:

//在指定文件创建模板和它的组件

const { notEmpty } = require('../utils.js');
const fs = require('fs');

let components = [];
const files = fs.readdirSync('src/view/');
files.forEach(item => {
  let stat = fs.lstatSync('src/view/' + item);
  if (stat.isDirectory() === true) {
    components.push(item);
  }
});

module.exports = {
  description: 'generate a cpv',
  prompts: [
    {
      type: 'input',
      name: 'name',
      message: 'cpv name please',
      validate: notEmpty('name')
    },
    {
      type: 'list',
      name: 'dirName',
      message: 'choose name please',
      choices: components,
      validate: notEmpty('dirName')
    },
    {
      type: 'checkbox',
      name: 'blocks',
      message: 'Blocks:',
      choices: [
        {
          name: '<template>',
          value: 'template',
          checked: true
        },
        {
          name: '<script>',
          value: 'script',
          checked: true
        },
        {
          name: 'style',
          value: 'style',
          checked: true
        }
      ],
      validate(value) {
        if (value.indexOf('script') === -1 && value.indexOf('template') === -1) {
          return 'View require at least a <script> or <template> tag.';
        }
        return true;
      }
    }
  ],
  actions: data => {
    const name = '{{name}}';
    const dirName = '{{dirName}}';
    const actions = [
      {
        type: 'add',
        path: `src/view/${dirName}/${name}/index.vue`,
        templateFile: 'plop-templates/cpv/index.hbs',
        data: {
          name: name,
          template: data.blocks.includes('template'),
          script: data.blocks.includes('script'),
          style: data.blocks.includes('style')
        }
      },
      {
        type: 'add',
        path: `src/view/${dirName}/component/CPV${name}.vue`,
        templateFile: 'plop-templates/cpv/component.hbs',
        data: {
          name: name,
          template: data.blocks.includes('template'),
          script: data.blocks.includes('script'),
          style: data.blocks.includes('style')
        }
      }
    ];

    return actions;
  }
};

参考