meta.js
December 22, 2021 · View on GitHub
用于控制模版最终渲染和生成的项目文件。
完整示例
module.exports = {
// generator钩子函数
hooks: {
beforeGenerate: (generator: Generator) => {
// warn:不建议return true, 如果返回值为true将终止后续流程
console.log('template beforeGenerate is run', generator);
// return true
},
afterGenerate: (generator: Generator) => {
console.log('template afterGenerate is run', generator);
},
/**
* 参考项目https://github.com/segmentio/metalsmith
* 以及@types/metalsmith
* 渲染占位符时的hook,如果配置了该函数,将由你自己接管渲染占位符
*/
renderTemplatePlaceholder: (generator: Generator) => {
return (files: IFiles, metalsmith: Metalsmith, done: Function) => {};
},
/**
* 最终渲染文件的hook,理论上可以做任何事包括渲染占位符
*/
renderTemplateFile: (generator: Generator) => {
return (files: IFiles, metalsmith: Metalsmith, done: Function) => {};
}
},
// handlebars的helpers扩展函数
// https://handlebarsjs.com/api-reference/runtime.html#handlebars-registerhelper-name-helper
helpers: {
if_equal(v1, v2, opts) {
return v1 === v2
? opts.fn(this)
: opts.inverse(this)
},
}
// 交互式问题
// 参考inquirer https://github.com/SBoudrias/Inquirer.js
prompts: [
{
name: 'projectDesc',
type: 'string',
require: false,
default: 'A test description',
message: 'A project description'
},
{
name: 'build',
type: 'list',
message: '构建方式',
choices: [
{
name: '快速构建方案',
value: 'platfomA',
short: 'platfomA',
},
{
name:'稳定构建方案',
value: 'platfomB',
short: 'platfomB',
},
]
},
{
name: 'router',
type: 'confirm',
message: '是否安装vue-router?'
},
{
// 当用户的build的选项为platfomA时执行此问题
when: (answer) => { return answer.build == 'platfomA' },
name: 'unit',
type: 'confirm',
message: '是否需要单元测试'
}
],
// 根据用户对相关name的回答,进行文件的过滤删除
// 遵循glob的语法 https://rgb-24bit.github.io/blog/2018/glob.html
filterFilesMap: {
'test/unit/**/*': 'unit',
'src/router/**/*': 'router'
}
// 编译白名单,考虑到handlebars编译{{ xxx }}的值时,可能会编译到一些不需要编译的文件导致报错
// 将需要handlebars需要编译的文件写在compileWhiteList中(默认会编写leorc.js和package.json,无需额外添加leorc.js和package.json)
// 若不传compileWhiteList或为空时,默认编译所有文件
// 遵循glob的语法 https://rgb-24bit.github.io/blog/2018/glob.html
compileWhiteList: [
'src/router/**/*',
'test/unit/**/*',
]
}
字段解释
prompts
类型: Array
定义: 模板配置询问阶段,模板开发者可设置一些选项供使用者选择,后期渲染阶段会根据用户的选择来控制模板的生成。
规范: 由于模板配置询问功能基于Inquirer.js实现,所以 prompts 书写的规则需遵循Inquirer.js规范。
示例:
prompts: [
{
name: 'build',
type: 'list',
message: '构建方式',
choices: [
{
name: '快速构建方案',
value: 'platfomA',
short: 'platfomA',
},
{
name:'稳定构建方案',
value: 'platfomB',
short: 'platfomB',
},
]
}
...
]
filterFilesMap
类型: Object
定义: 获取模板配置询问用户的配置选择,过滤掉不需要生成的文件。
::: tip
filterFilesMap是由文件名作为key,prompts问题中的 name 字段作为value的一个对象,例如:
prompts: [
{
name: 'router',
type: 'confirm',
message: '是否安装react-router?'
}
]
filterFilesMap: {
'src/router/**/*': 'router'
}
若用户 router 选项选择了 N,则最终不会生成 src 下 router 及 router 目录下所有文件。 :::
规范: 文件名的书写规范遵循glob 的语法
helpers
类型: Object
定义: 支持模版开发者在开发中使用 Handlebars 的 helpers 控制文件内容的生成。
规范: helpers 函数规范遵循Handlebars 的 registerHelper规则。
示例:
helpers: {
if_equal(v1, v2, opts) {
return v1 === v2
? opts.fn(this)
: opts.inverse(this)
},
}
compileWhiteList
类型: Array
定义: 模版编译白名单。
::: v-pre
::: tip
由于handlebars是根据双花括号{{}}去匹配并渲染变量。当在react或者vue的项目中,其内部语法 {{variable}}与handlebars语法{{replaceName}}冲突,若希望{{variable}}不被handlebars编译,可在变量前添加转义符{{variable}}写作\{{variable}}来防止handlebars编译变量。
除了上述的方法可以阻止 handlebars 编译,还可以将需要编译文件写入compileWhiteList中,这样只会编译compileWhiteList中文件,由于 generator 会默认编译 leorc.js 和 package.json 文件所以无需额外填写。若compileWhiteList为空默认编译项目所有文件。
:::
示例:
compileWhiteList: ['src/router/**/*', 'test/unit/**/*'];
// 实际编译文件有'src/router/**/*', 'test/unit/**/*', 'package.json', 'leorc.js'
规范: 文件名的书写规范遵循glob 的语法
hooks
快速理解不同 hooks 执行的时机可参考此处。
hook.beforeGenerate
类型: Function
定义: 此函数为 Generator 的前置 hook 函数,此函数不建议 return true, 如果返回值为 true 将终止后续流程。
hooks.afterGenerate
类型: Function
定义: 此函数为 Generator 的后置 hook 函数。
hooks.renderTemplatePlaceholder
类型: Function
定义: 渲染占位符时的 hook 函数,如果配置了该函数,将由模版开发者模版控制占位符的渲染。
hooks.renderTemplateFile
类型: Function
定义: 最终渲染文件的 hook,此函数为最终文件的生成函数。
示例:
hooks: {
beforeGenerate: (generator: Generator) => {},
afterGenerate: (generator: Generator) => {},
renderTemplatePlaceholder: (generator: Generator) => {
return (files: IFiles, metalsmith: Metalsmith, done: Function) => {};
},
renderTemplateFile: (generator: Generator) => {
return (files: IFiles, metalsmith: Metalsmith, done: Function) => {};
}
},