自动化文件创建-plop使用介绍

401 阅读4分钟

自动化文件创建-plop使用介绍

介绍

plop是一个用于自动化创建、修改文件的小工具。在维护代码的过程中,我们常常遇到需要在项目中四处寻求最佳实践的文件,比如说创建一个页面时,需要编写页面、样式、README文档、在路由配置中添加对应的路由信息等,如果对项目不熟悉的情况下,可能需要花时间查看其他页面并拷贝所需部分的代码来创建新页面。有了plop后,就可以通过几个简单的问答,直接将文件创建好,节约开发时间。

plop基于inquirerhandlebar两个库。利用inquirer实现收集用户输入数据,借助handlebar生成指定模板的文本。根据plopfile中的配置,最终进行文件的创建或修改。

安装

  1. 添加plop库
yarn add --dev plop
  1. 修改package.json,添加script:"plop": "plop",
  2. 在根目录下创建plopfile.js文件
module.exports = function (plop) {
  // create your generators here
  plop.setGenerator('basics', {
      description: 'this is a skeleton plopfile',
      prompts: [], // array of inquirer prompts
      actions: []  // array of actions
  });
};
  1. 执行yarn plop指令

使用

plop通过plop.setGenerator的api函数创建整个自动化流程。description是一个可选字符串,描述流程的作用;prompts是一系列的问题,用于收集生成模板所需的数据。actions则是一系列的行为,包括新增文件、修改文件或是其他自定义行为。

下面通过几个例子来了解如何使用plop。

1. 基础使用

plop.setGenerator('basics', {
  description: '基础使用',
  prompts: [
    {
      type: 'input',
      name: 'filePath',
      message: '请输入页面路径。',
    },
  ],
  actions: [
    {
      type: 'add',
      path: '{{filePath}}',
    },
  ],
});

actions的path字段接受handlebar式的模板字符串,即可使用双括号访问从prompts获取到的数据。

2. 对用户输入添加校验


plop.setGenerator('page', {
  description: '创建多语言页面',
  prompts: [
    {
      type: 'input',
      name: 'filePath',
      message: '请输入页面路径。例如 `kebab-case/kebab-case`',
      validate(input) {
        if (!input) {
          return '请输入页面地址';
        }
        return true;
      },
    },
  ],
  actions: [
    {
      type: 'add',
      path: '{{filePath}}',
    },
  ],
});

prompts字段是基于Inquirer,可拓展的功能有validate(数据校验)、choices(选项)、default(默认值)等。具体参照Inquirer文档

3. 通过模板文件进行新增

首先创建模板文件

// config/plop-templates/page.hbs
import React from 'react'
export default function {{name}}() {
  return <div></div>;
}

再修改setGenerator函数

plop.setGenerator('basics', {
  description: '模板文件',
  prompts: [
    {
      type: 'input',
      name: 'name',
      message: '请输入名称。',
    },
  ],
  actions: [
    {
      type: 'add',
      templateFile: 'config/plop-templates/page.hbs',
      path: 'src/page/index.tsx',
    },
  ],
});

在模板文件中使用的是handlebar的语法,双括号除了引用参数外,还有类似vue中的Filter语法的Helper,其中内置的一些逻辑判断、循环等工具方法。具体查看handlebars文档

  1. 修改文本

修改文件有两种形式,一种是通过pattern参数,正则匹配并替换文本。另一种是通过transform函数。transform函数会接收整个文件的文本作为参数,再返回修改后的文本替代原文件。

以下是一个添加路由配置的例子。

  1. 首先在路由原文件加上替换标识。
const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
  },
  ...
  {
    path: "contacts/:contactId",
    element: <Contact />,
  },
+ // add plop config
]);
  1. 添加替换模板文件config/plop-templates/modify.hbs
  {
    path: "{{path}}",
    element: <{{name}} />,
  },
  // append plop config
  1. 再修改setGenerator函数
plop.setGenerator('basics', {
  description: '模板文件',
  prompts: [
    {
      type: 'input',
      name: 'name',
      message: '请输入名称。',
    },
    {
      type: 'input',
      name: 'path',
      message: '请输入路由。',
    },
  ],
  actions: [
    {
      type: 'modify',
      path: 'src/router.js',
      pattern: /\/\/ append plop config/,
      templateFile: 'config/plop-templates/modify.hbs',
    },
  ],
});

4. 动态actions

actions除了可以为数组外,还可以使用一个返回数组的函数,通过判断用户输入的数据,选择性的执行命令,还可以修改传入模板的数据。


plop.setGenerator('basics', {
  description: '动态actions',
  prompts: [
    {
      type: 'confirm',
      name: 'isNeedREADME',
      message: '是否需要README',
    },
  ],
  actions: (data) => {
    let list = [
      {
        type: 'add',
        path: 'src/page/index.tsx',
        data: {
          ...data,
          othersData: null,
        },
      },
    ];
    if (data.isNeedREADME) {
      list.push({
        type: 'add',
        path: 'src/page/README.md',
      });
    }
    return list;
  },
});

总结

plop是一个简单小巧实用的工具,但官方文档主要以文本描述为主,初次使用时可能会感觉比较枯燥,希望通过本文的几个针对具体场景的例子,可以帮助大家更快上手。

参考链接

plop-git

inquirer

handlebars文档

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 3 天