1、准备
乐高组件库地址
在 haha-cli-dev-template 这个模块下,新建目录 haha-cli-dev-lego-components, 把下载后的代码改为 template 放在这个目录下。
修改 package.json, 删掉 file 字段(因为有file,会导致只上传dest文件的内容),npm publish
"name": "<%= className %>",
"version": "<%= version %>",
"description": "<%= description %>",
数据库中,添加tag、igore字段。
后台系统修改model
'use strict'
module.exports = app => {
const { STRING, INTEGER } = app.Sequelize
const Templates = app.model.define('templates', {
id: { type: INTEGER, primaryKey: true, autoIncrement: true, allowNull: false, comment: '模板id' },
name: { type: STRING(255), allowNull: false, comment: '名称' },
npmName: { type: STRING(255), allowNull: false, comment: '模板名称' },
version: { type: STRING(255), allowNull: false, comment: '模板版本' },
npmType: { type: STRING(255), allowNull: false, comment: '是否是标准模板' },
installCommand: { type: STRING(255), allowNull: false, comment: '安装依赖命令' },
startCommand: { type: STRING(255), allowNull: false, comment: '启动命令' },
tag: { type: STRING(255), allowNull: false, comment: '标签' },
ignore: { type: STRING(255), allowNull: false, comment: '忽略的文件' }
})
return Templates
}
2、项目和组件模板数据隔离+动态配置 ejs 的 ignore
//标准安装
async installNormalTemplate() {
...
const ignore = ['**/node_modules/**', ...this.template?.ignore.split(',')]
...
}
//如果模板中存在 png 等类型的文件,导致 ejs 渲染失败,都可以加在 ignore 中(**.png)
createTemplateChoice(type) {
return this.templates
.filter(item => item.tag === type)
?.map(item => ({
name: item.name,
value: item.npmName
}))
}
3、获取组件信息功能开发
//3、选择创建项目或组件
async getBaseInfo() {
let info = {}
function isNamevalid(val) {
return /^[a-zA-Z]+([-][a-zA-Z0-9]|[_][a-zA-Z0-9]|[a-zA-Z0-9])*$/.test(val)
}
const { type } = await inquirer.prompt({
type: 'list',
message: '请选择初始化类型',
name: 'type',
default: TYPE_PROJECT,
choices: [
{
name: '项目',
value: TYPE_PROJECT
},
{
name: '组件',
value: TYPE_COMPONENT
}
]
})
const title = TYPE_PROJECT === type ? '项目' : '组件'
const promptArr = [
{
type: 'input',
message: `请输入${title}版本号`,
name: 'version',
default: '1.0.0',
validate: val => !!semver.valid(val) || '请输入合法的版本号',
filter: val => {
if (!!semver.valid(val)) {
return semver.valid(val)
}
return val
}
},
{
type: 'list',
message: `请选择${title}模板`,
name: 'npmName',
choices: this.createTemplateChoice(type)
}
]
const projectPromt = {
type: 'input',
message: `请输入${title}名称`,
name: 'project',
default: 'HahaDemo',
validate: function (val) {
//检查项目名称和版本号的合法性
const done = this.async()
setTimeout(function () {
//1、必须首字母大写,
//2、尾字符必须为英文或者数字,不能为字符
//3、字符仅允许'-_'
//类型合法有:a a-b a_b a-b-c a_b_c a1_b1_c1 a1 a1-b1-c1
if (!isNamevalid(val)) {
done(`请输入合法的${title}名称(要求英文字母开头,数字或字母结尾,字符只允许使用 - 以及 _)`)
return
}
done(null, true)
}, 0)
}
}
//命令行输入的projectName是否合法,不合法则重新填入项目名称
if (!isNamevalid(this.projectName)) {
promptArr.unshift(projectPromt)
} else {
info.project = this.projectName
}
if (type === TYPE_COMPONENT) {
const descriptPrompt = {
type: 'input',
message: `请输入${title}描述`,
name: 'descript',
validate: val => {
if (!val) {
return '组件描述不可以为空'
}
return true
}
}
promptArr.push(descriptPrompt)
}
const result = await inquirer.prompt(promptArr)
if (result?.project) {
info.project = result?.project
}
//4、获取项目的基本信息
return {
type,
...result,
...info,
className: require('kebab-case')(info.project).replace(/^-/, '')
}
}