Building a Vue3 component library from 0 (10): How to build a Cli scaffolding

This article will implement a create-easyestdevelopment called scaffolding, which npm init easyestcan pull the entire component library development framework locally with just one command.

Create Cli package

First, we create a new cli directory under the packages directory, pnpm initinitialize with the execution, and then change the package name tocreate-easyest

What we need to know here is that when we execute npm init xxxor npm create xxx, we actually execute npx create-xxx, so when we execute npm init easyest, we actually executenpx create-easyest

When we execute, create-easyestthe path corresponding to the bin under package.json will be executed, so we will package.jsonmodify it to

{
    
    
  "name": "create-easyest",
  "version": "1.0.0",
  "description": "",
  "bin": "index.js",
  "keywords": [],
  "author": "",
  "license": "MIT"
}


At the same time, create a new index.js as the entry file, pay attention to add #! /usr/bin/env node at the beginning

#! /usr/bin/env node

Handle user input commands with command-line-args

In fact, there are many plug-ins for processing user input parameters, such as CAC, Yargs, Commander.js, command-line-args, etc., but in my opinion, command-line-args is the easiest to use, so use command-line- args for user parameter parsing

pnpm add command-line-args

Create a new cli.js to handle the logic of our scaffolding, here simply write a -v version command

import commandLineArgs from "command-line-args";
import {
    
     readFile } from "fs/promises";

const pkg = JSON.parse(
  await readFile(new URL("./package.json", import.meta.url))
);
//配置命令参数
const optionDefinitions = [{
    
     name: "version", alias: "v", type: Boolean }];
const options = commandLineArgs(optionDefinitions);
if (options.version) {
    
    
  console.log(`v${
      
      pkg.version}`);
}

insert image description here
We can also use the command-line-usage plugin to let it provide us with help commands

pnpm add command-line-usage

Only the relevant code is pasted here

import commandLineArgs from "command-line-args"
import commandLineUsage from "command-line-usage"
...

//帮助命令
const helpSections = [
  {
    
    
    header: 'create-easyest',
    content: '一个快速生成组件库搭建环境的脚手架',
  },
  {
    
    
    header: 'Options',
    optionList: [
      {
    
    
        name: 'version',
        alias: 'v',
        typeLabel: '{underline boolean}',
        description: '版本号',
      },
      {
    
    
        name: 'help',
        alias: 'h',
        typeLabel: '{underline boolean}',
        description: '帮助',
      }
    ],
  },
];


if (options.help) {
    
    
  console.log(commandLineUsage(helpSections))
  return
}

insert image description here

interactive command

When we use some scaffolding, such as create-vite, it will give us some options for us to choose

insert image description here
So our scaffolding should also have this function, but how should this be realized?

In fact, it is very simple. We only need the prompts plug-in. It can configure what the user enters and whether it is single-choice or multiple-choice. First, install prompts

pnpm add prompts

Then in cli.js

import prompts from "prompts";
const promptsOptions = [
  {
    
    
    type: "text",
    name: "user",
    message: "用户",
  },
  {
    
    
    type: "password",
    name: "password",
    message: "密码",
  },
  {
    
    
    type: "select", //单选
    name: "gender",
    message: "性别",
    choices: [
      {
    
     title: "男", value: 0 },
      {
    
     title: "女", value: 1 },
    ],
  },
  {
    
    
    type: "multiselect", //多选
    name: "study",
    message: "选择学习框架",
    choices: [
      {
    
     title: "Vue", value: 0 },
      {
    
     title: "React", value: 1 },
      {
    
     title: "Angular", value: 2 },
    ],
  },
];

const getUserInfo = async () => {
    
    
  const res = await prompts(promptsOptions);
  console.log(res);
};
getUserInfo();

Then we can process different logics according to the corresponding values. Of course, our scaffolding does not need so many parameters, we can change it to the following options

const promptsOptions = [
  {
    
    
    type: "text",
    name: "project-name",
    message: "请输入项目名称",
  },
  {
    
    
    type: "select", //单选
    name: "template",
    message: "请选择一个模板",
    choices: [
      {
    
     title: "kitty-ui", value: 0 },
      {
    
     title: "easyest", value: 1 },
    ],
  },
];

Then we can pull different warehouses according to the user's choice

Pull remote warehouse template

To pull the remote warehouse, we can use the download-git-repo tool, and then use its clone method. At the same time, we need to install a loading plugin ora and a log color plugin chalk

pnpm add download-git-repo ora chalk
//gitClone.js

import download from "download-git-repo";
import chalk from "chalk";
import ora from "ora";

export default (remote, name, option) => {
    
    
  const downSpinner = ora("正在下载模板...").start();
  return new Promise((resolve, reject) => {
    
    
    download(remote, name, option, (err) => {
    
    
      if (err) {
    
    
        downSpinner.fail();
        console.log("err", chalk.red(err));
        reject(err);
        return;
      }
      downSpinner.succeed(chalk.green("模板下载成功!"));
      resolve();
    });
  });
};

//cli.js
const remoteList = {
    
    
  1: "https://gitee.com/geeksdidi/kittyui.git",
  2: "https://github.com/qddidi/easyest.git",
};
const getUserInfo = async () => {
    
    
  const res = await prompts(promptsOptions);
  if (!res.name || !res.template) return;
  gitClone(`direct:${
      
      remoteList[res.template]}`, res.name, {
    
    
    clone: true,
  });
};

Then after the execution is complete, there will be our template in the directory

insert image description here
Finally, just publish our create-easyest, which has been introduced before, so I won’t go into details here. I have already released it here, let's find a folder to try it out npm create easyest, and we found that the easyest project has also been cloned

Guess you like

Origin blog.csdn.net/weixin_45821809/article/details/130352761