【架构师(第十九篇)】脚手架之组件库模板开发

1,591 阅读2分钟

乐高组件库模板开发

👉👉 乐高组件库地址

hzw-cli-dev-template 这个模块下,新建目录 hzw-cli-dev-lego-components, 把下载后的代码改为 template 放在这个目录下。

image.png

修改 package.json, 删掉 file 字段。

  "name": "<%= className %>",
  "version": "<%= version %>",

发布到 npm

数据库新添加一条,并给每条数据添加 tag 字段 ,以及 ignore 字段。

image.png

项目和组件模板数据隔离+动态配置 ejs 的 ignore

commands\init\lib\index.js getInfo

this.template = this.template.filter((item) => item.tag.includes(type))

commands\init\lib\index.js installNormalTemplate

// ejs 模板渲染
const ignore = ['node_modules/**', ...this.templateInfo.ignore]

如果模板中存在 png 等类型的文件,导致 ejs 渲染失败,都可以加在 ignore 中。

获取组件信息功能开发

commands\init\lib\index.js getInfo

这个方法兼容组件以后变的很长,下次要好好重构一下。

/**
   * @description: 选择创建项目或者组件 获取项目的基本信息 return Object
   * @param {*}
   * @return {*} 项目的基本信息
   */
  async getInfo() {
    let info = {};
    // 选择创建项目或者组件;
    const {
      type
    } = await inquirer.prompt({
      type: 'list',
      message: '请选择初始化类型',
      name: 'type',
      default: TYPE_PROJECT,
      choices: [{
        name: '项目',
        value: TYPE_PROJECT,
      },
      {
        name: '组件',
        value: TYPE_COMPONENT,
      },
      ],
    });
    log.verbose('type', type);
    this.template = this.template.filter((item) => item.tag.includes(type))
    const title = TYPE_PROJECT === type ? '项目' : '组件'

    const isValidateName = (a) => {
      const reg =
        /^[a-zA-Z]+([-][a-zA-Z0-9]|[_][a-zA-Z0-9]|[a-zA-Z0-9])*$/;
      return reg.test(a)
    }
    // 是否在执行init 命令的时候就传入了正确的项目名称
    const isTrueName = isValidateName(this.projectName)

    const promptArr = [{
      type: 'input',
      message: `请输入${title}版本号`,
      name: 'version',
      default: '1.0.0',
      validate: (a) => {
        return !!semver.valid(a) || '请输入合法的版本号';
      },
      filter: (a) => {
        if (!!semver.valid(a)) {
          return semver.valid(a);
        }
        return a;
      },
    },
    {
      type: 'list',
      message: `请选择${title}模板`,
      name: 'template',
      default: 'vue3',
      choices: this.createTemplateChoices()
    },]
    const projectPrompt = {
      type: 'input',
      message: `请输入${title}名称`,
      name: 'project',
      validate: (a) => {
        if (isValidateName(a)) {
          return true;
        }
        return '要求英文字母开头,数字或字母结尾,字符只允许使用 - 以及 _ ';
      },
    }
    if (isTrueName) {
      info.project = this.projectName
    } else {
      promptArr.unshift(projectPrompt)
    }

    // 获取组件的基本信息;
    if (type === TYPE_COMPONENT) {
      const descriptPrompt = {
        type: 'input',
        message: '请输入组件描述',
        name: 'description',
        validate: (a) => {
          if (a) {
            return true;
          }
          return '组件描述不可以为空';
        },
      }
      promptArr.push(descriptPrompt)
      const answers = await inquirer.prompt(promptArr);
      info = {
        ...info,
        ...answers,
        type,
      };
    }
    // 获取项目的基本信息;
    if (type === TYPE_PROJECT) {
      const answers = await inquirer.prompt(promptArr);
      info = {
        ...info,
        ...answers,
        type,
      };
    }
    // 将项目名称改成连接线形式
    if (info.project) {
      // kebab-case 这个库如果是大写字母开头会多出一个 - , 所以使用 replace 把第一个 - 给去掉
      info.className = require('kebab-case')(info.project).replace(/^-/, '')
    }
    return info;
  }