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.Sequelizeconst 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-c1if (!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(/^-/, '')}}
