Actions:生成器能执行哪些动作
🎯 引言
学完这篇文章,你将掌握 Plop 中最常用的几个动作:add 创建文件、modify 修改文件、addMany 批量创建文件。它们是每个生成器的“执行引擎”。
🧱 actions 的基本结构
actions 是一个数组,每个元素描述一个要执行的动作。Plop 会按顺序依次执行。
actions: [
{
type: 'add',
path: 'src/components/{{pascalCase name}}.vue',
templateFile: 'plop-templates/component.hbs'
}
]
每个动作至少有 type 字段,不同的 type 对应不同的行为。
✨ add:创建单个文件
add 是最常用的动作,用于根据模板创建一个新文件。
{
type: 'add',
path: 'src/components/{{pascalCase name}}.vue',
templateFile: 'plop-templates/component.hbs'
}
| 字段 | 说明 |
|---|---|
path | 生成的目标文件路径,支持模板变量 |
templateFile | 模板文件路径 |
template | 直接写模板字符串(与 templateFile 二选一) |
如果不想单独维护模板文件,也可以直接写 template:
{
type: 'add',
path: 'src/components/{{pascalCase name}}.vue',
template: '<template>\n <div>{{name}}</div>\n</template>\n'
}
template 适合一两行的简单片段。✨ modify:修改已有文件
modify 用来在已有文件里查找并替换内容,适合往已有目录或配置里追加内容。
{
type: 'modify',
path: 'src/router/index.js',
pattern: /\/\/ 请在这里导入路由/,
template: "import {{pascalCase name}} from '@/views/{{pascalCase name}}.vue';\n// 请在这里导入路由"
}
上面的例子会在 // 请在这里导入路由 这一行的前面插入一条 import 语句。
| 字段 | 说明 |
|---|---|
path | 要修改的文件路径 |
pattern | 用于匹配替换位置的正则表达式或字符串 |
template | 替换后的内容 |
templateFile | 也可以从文件读取替换内容 |
modify 时要特别小心 pattern 的写法。如果匹配失败,原文件不会被修改,建议先在副本上测试。✨ addMany:批量创建文件
当一次需要生成多个相关文件时,用 addMany 可以简化配置。
{
type: 'addMany',
destination: 'src/components/{{pascalCase name}}',
templateFiles: 'plop-templates/component/**'
}
假设 plop-templates/component/ 目录下有以下文件:
plop-templates/component/
├── index.vue
├── index.js
└── style.scss
执行后会在 src/components/UserInfo/ 下生成对应的 index.vue、index.js、style.scss。
| 字段 | 说明 |
|---|---|
destination | 目标目录 |
templateFiles | 模板文件匹配规则,支持通配符 |
base | 去掉模板路径中的前缀目录 |
component 这一层目录,可以加 base: 'plop-templates/component'。🛠 综合示例:组件 + 样式 + 路由注册
下面这个生成器会同时完成三件事:
- 创建组件文件。
- 创建样式文件。
- 在路由文件里自动导入新页面。
export default function (plop) {
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'
},
{
type: 'add',
path: 'src/views/{{pascalCase name}}Page.scss',
templateFile: 'plop-templates/page.scss.hbs'
},
{
type: 'modify',
path: 'src/router/index.js',
pattern: /\/\/ 请在这里导入页面/,
template: "import {{pascalCase name}}Page from '@/views/{{pascalCase name}}Page.vue';\n// 请在这里导入页面"
}
]
});
}
path 和 template 里都支持 Handlebars 变量。你可以把同一个 name 用 pascalCase、kebabCase、camelCase 等不同格式渲染。⚡ abortOnFail:动作失败时是否停止
默认情况下,如果某个动作执行失败,Plop 会停止后续动作。你可以通过 abortOnFail 控制这个行为。
{
type: 'add',
path: 'src/components/{{pascalCase name}}.vue',
templateFile: 'plop-templates/component.hbs',
abortOnFail: false
}
设为 false 后,即使这个动作失败,Plop 也会继续执行后面的动作。
💡 skip 函数:动态决定是否执行
每个动作还可以加 skip 函数,根据用户答案决定是否跳过。
{
type: 'add',
path: 'src/components/{{pascalCase name}}.test.js',
templateFile: 'plop-templates/test.hbs',
skip: function (answers) {
if (!answers.hasTest) {
return '跳过测试文件生成';
}
}
}
如果 skip 返回字符串,这个动作就会被跳过,并显示提示信息。
🧾 小节总结
add用于创建单个文件,是最常用的动作。modify用于修改已有文件内容,适合追加导入、注册路由等场景。addMany用于批量创建一组文件。abortOnFail控制动作失败时是否停止。skip函数可以动态决定是否执行某个动作。
❓ 知识问答
Q1:add 的 template 和 templateFile 有什么区别?
A:template 直接写模板字符串,templateFile 从文件读取模板内容。复杂模板推荐用 templateFile。
Q2:modify 会覆盖整个文件吗?
A:不会。它只替换 pattern 匹配到的部分,其余内容保持不变。
Q3:addMany 的 destination 和 path 有什么区别?
A:add 用 path 指定单个文件;addMany 用 destination 指定目标目录,会根据模板目录批量生成多个文件。
Q4:多个动作是按顺序执行的吗?
A:是的。actions 数组里的动作会按顺序依次执行。
🧪 小练习
请补全下面的动作配置,让它在创建组件的同时,自动创建一个同名的测试文件:
{
type: 'add',
path: 'src/components/{{pascalCase name}}.vue',
templateFile: 'plop-templates/component.hbs'
},
// 请在这里添加一个动作,生成 src/components/{{pascalCase name}}.test.js
🎉 恭喜你掌握了 Plop 的核心动作!下一篇我们会学习模板语法,理解 Handlebars 在 Plop 中的具体用法。
