Plop 简介

编写 plopfile:定义你的第一个生成器

掌握 plopfile.mjs 的基本结构,学会用 setGenerator 定义生成器,并通过命令行运行它。

🎯 引言

学完这篇文章,你将掌握 Plop 的核心配置文件 plopfile.mjs 的结构,学会定义一个完整的生成器,并通过命令行运行它。


🧱 plopfile.mjs 的作用

plopfile.mjs 是 Plop 的入口配置文件。它导出一个默认函数,Plop 启动时会调用这个函数,并把 plop 实例传进来。

最基本的形式如下:

plopfile.mjs
export default function (plop) {
    // 在这里注册生成器、辅助函数等
}

这个函数里通常会做三件事:

  1. 注册生成器:用 plop.setGenerator() 定义可以被执行的任务。
  2. 注册辅助函数:用 plop.setHelper() 扩展模板语法。
  3. 注册 partial:用 plop.setPartial() 定义可复用的模板片段。

本节课我们先聚焦最常用的第一项:注册生成器。


✨ 用 setGenerator 定义生成器

setGenerator 接收两个参数:生成器名称和配置对象。

plopfile.mjs
plop.setGenerator('component', {
    description: '创建一个 Vue 组件',
    prompts: [
        // 交互式问题
    ],
    actions: [
        // 要执行的动作
    ]
});

配置对象包含三个核心字段:

字段作用
description生成器的描述,运行 npx plop 时可以看到
prompts一个数组,每个元素是一个问题对象
actions一个数组,每个元素是一个动作对象

🛠 一个更完整的生成器

下面我们定义一个生成 API 接口文件的生成器:

plopfile.mjs
export default function (plop) {
    plop.setGenerator('api', {
        description: '创建一个 API 接口文件',
        prompts: [
            {
                type: 'input',
                name: 'name',
                message: '请输入接口名称(如 getUser)'
            }
        ],
        actions: [
            {
                type: 'add',
                path: 'src/api/{{camelCase name}}.js',
                templateFile: 'plop-templates/api.hbs'
            }
        ]
    });
}

对应的模板文件 plop-templates/api.hbs

plop-templates/api.hbs
import request from '@/utils/request';

export function {{camelCase name}}(params) {
    return request({
        url: '/{{kebabCase name}}',
        method: 'get',
        params
    });
}

运行:

npx plop api

输入 getUser 后,会生成 src/api/getUser.js

src/api/getUser.js
import request from '@/utils/request';

export function getUser(params) {
    return request({
        url: '/get-user',
        method: 'get',
        params
    });
}
camelCase 会把输入转成“小驼峰”,kebabCase 会转成“短横线连接”。这样同一个输入可以自动适配不同的命名规范。

⚡ 定义多个生成器

一个项目里通常不止一种文件需要生成。你可以在 plopfile.mjs 中注册多个生成器:

plopfile.mjs
export default function (plop) {
    plop.setGenerator('component', {
        description: '创建 Vue 组件',
        prompts: [{ type: 'input', name: 'name', message: '组件名称' }],
        actions: [
            {
                type: 'add',
                path: 'src/components/{{pascalCase name}}.vue',
                templateFile: 'plop-templates/component.hbs'
            }
        ]
    });

    plop.setGenerator('api', {
        description: '创建 API 接口文件',
        prompts: [{ type: 'input', name: 'name', message: '接口名称' }],
        actions: [
            {
                type: 'add',
                path: 'src/api/{{camelCase name}}.js',
                templateFile: 'plop-templates/api.hbs'
            }
        ]
    });

    plop.setGenerator('page', {
        description: '创建页面文件',
        prompts: [{ type: 'input', name: 'name', message: '页面名称' }],
        actions: [
            {
                type: 'add',
                path: 'src/views/{{pascalCase name}}Page.vue',
                templateFile: 'plop-templates/page.hbs'
            }
        ]
    });
}

运行 npx plop 不加参数时,Plop 会列出所有可用的生成器,让你选择:

$ npx plop
? [PLOP] Please choose a generator (Use arrow keys)
 component - 创建 Vue 组件
  api - 创建 API 接口文件
  page - 创建页面文件

🧰 命令行小技巧

除了交互式选择,你也可以直接在命令行指定生成器和参数:

# 指定生成器
npx plop component

# 直接传入参数,跳过提问
npx plop component -- --name UserInfo
注意 -- 后面的参数才会传给 Plop。--name 对应的是 promptsname 字段的值。

🧾 小节总结

  • plopfile.mjs 是 Plop 的配置入口,默认导出一个接收 plop 实例的函数。
  • plop.setGenerator() 用于注册生成器,包含 descriptionpromptsactions
  • 一个项目可以注册多个生成器,分别生成不同类型的文件。
  • 运行 npx plop 可以交互选择,运行 npx plop 生成器名 可以直接执行指定生成器。

❓ 知识问答

Q1:plopfile.mjs 可以改成 plopfile.js 吗?

A:可以,但需要在 package.json 里设置 "type": "module"。否则 Node.js 会按 CommonJS 解析,export default 会报错。

Q2:生成器名称可以重复吗?

A:不建议重复。如果重复注册同名生成器,后面的会覆盖前面的。

Q3:description 是必填的吗?

A:不是必填,但建议写上。运行 npx plop 时,description 会帮助你和队友快速识别生成器的作用。

Q4:可以在一个 plopfile.mjs 里放多个 setGenerator 吗?

A:完全可以。推荐把同一项目里常用的生成功能都写在一个配置文件中,方便维护。


🧪 小练习

请在刚才的 plop-demo 项目中完成以下任务:

  1. plopfile.mjs 中新增一个名为 util 的生成器。
  2. 该生成器询问工具函数名称,并在 src/utils/{{camelCase name}}.js 生成文件。
  3. 模板内容如下,请补全路径和变量:
plopfile.mjs
plop.setGenerator('util', {
    description: '创建一个工具函数',
    prompts: [
        {
            type: 'input',
            name: 'name',
            message: '请输入工具函数名称'
        }
    ],
    actions: [
        {
            type: 'add',
            // 请在这里补全 path
            templateFile: 'plop-templates/util.hbs'
        }
    ]
});

🎉 恭喜你掌握了 Plop 生成器的基本配置!下一篇我们会学习 prompts,让生成器提出更灵活的交互问题。