I’m participating in nuggets Creators Camp # 4, click here to learn more and learn together!

Hello everyone, I am little Dudu, following the last 10 minutes, to build a proprietary CLI for you, we have completed the project download, install and run. (The new friends can take a quick look at it first.)

We have a situation in project development where pages are developed with the same module, like this

What other way to do repetitive things like imported files, fixed labels, components, etc. in seconds than copy and paste? At this time we can use cli, let him help us achieve faster

The final result

Let’s take a look at the final result:

Simply say is through the interaction, automatic file creation and route configuration of these two functions

tip

NPM link can be used locally without sending packets

project

Here I use my personal Ant-design-pro-V5 to explain (different projects, different configurations oh ~).

Create a file

Let’s start by thinking about the steps needed to create a file. First we need to define such a template to build quickly, and then copy the template to our own project.

So let’s create a file here, such as:

Then we’ll go through the folder and copy the file out with copyFile

    const fileModule = resolve(__dirname, '.. /.. /module')
    const files = fs.readdirSync(fileModule).filter((v) = >! [".git"].includes(v));

    // Iterate over the required files to perform the copy
    files.map(async (item) => {
      const fromFileName = resolve(__dirname, `.. /.. /module/${item}`);
      const toFileName = resolve(__dirname, `${desc}/${item}`);
      fs.copyFile(fromFileName, toFileName, 0.() = >{})})Copy the code

So here we can optimize, we can check if the file that we’re creating has been created, and if it has, we can pop a box and say, this file is already created, do we want to delete it and reintroduce it, so let’s talk about how to delete the file

To delete a file, you need to delete all the subfiles in the file. To delete a directory file, use the fs.unlinkSync and fs.rmdirSync methods, along with some hints

  // desc: file directory
  const files = fs.readdirSync(desc)
  files.map((item) = > {
    fs.unlinkSync(`${desc}/${item}`)
  })
  fs.rmdirSync(desc)
Copy the code

Detailed code

create.ts:

const inquirer = require("inquirer");
const { resolve } = require("path");
const fs = require("fs");const { log } = require(".. /api"); 

const filePath = 'src/pages'

module.exports = async() = > {console.log("path", resolve("."));
  create()
};

async function create(){
  // Project name
  const name = await inquirer.prompt([{
    type: 'input'.message: 'Set file name 😎😎😎'.name: 'name',}])const desc = resolve(`. /${filePath}/${name.name}`);
  log(desc)

  // Check whether the file exists. If so, no message is displayed
  const isFile = fs.existsSync(desc)
  if(isFile){
    deleteFile(desc)
    return
  }else{
    await require(`./routes`)(name.name);
    createFile(desc)
    return}}async function createFile(desc){
  try{
    // Create a folder
    fs.mkdirSync(desc)

    const fileModule = resolve(__dirname, '.. /.. /module')
    const files = fs.readdirSync(fileModule).filter((v) = >! [".git"].includes(v));

    // Iterate over the required files to perform the copy
    files.map(async (item) => {
      const fromFileName = resolve(__dirname, `.. /.. /module/${item}`);
      const toFileName = resolve(__dirname, `${desc}/${item}`);
      fs.copyFile(fromFileName, toFileName, 0.() = >{})})}catch {
    log('Creation failed'.'red')}}async function deleteFile(desc){
  log(desc)
  try{
    // Whether to delete and re-establish
    const answer = await inquirer.prompt([{
      type: 'confirm'.name: 'confirm'.message: 'The current file already has this file, do you want to delete and then rebuild? '.default: false
    }])
    console.log("answer", answer);
    if(answer.confirm){
       // To delete modules, you need to delete files before deleting directories
      const files = fs.readdirSync(desc)
      files.map((item) = > {
        fs.unlinkSync(`${desc}/${item}`)
      })
      fs.rmdirSync(desc)
      await require(`./routes`)(answer.name);
      createFile(desc)
    }else{
      create()
    }
  } catch {
    log('Error occurred'.'red')}}Copy the code

Create routing

Let’s start with routing in V5:

As we can see, the general structure of the file is like this. In fact, it is not hard to find that we do not need to touch the route, so we can create a separate route module and then manually add it to the project

Effect:

We take the scaffolding to create a file for Routeschildren. ts where we need to note two points

  • There is noroutesChildren.tsLet’s just add it
  • There areroutesChildren.tsSo when we read this file, we need to read the file and splice it

Note: Fs. readFile and fs.writeFile require both strings, so HERE I intercept export default

Once we have created routesChildren.ts, we need to manually introduce routesChildren.ts into routes

    async function create(nameFile){
      const desc = resolve(`. /${filePath}`);
      const isFile = fs.existsSync(desc)
      const toFileName = resolve(__dirname, desc);

      / / write
      const start = `export default`

      if(isFile){
        fs.readFile(toFileName, 'utf8'.async (err, data) => {
          try{
            const arr = JSON.parse(data.substring(14, data.length).trim())
            const routerArr = await routerConfig(nameFile)
            const res = [...arr, ...routerArr]

            fs.writeFile(toFileName, `${start} The ${JSON.stringify(res)}`.(err) = > {
              log('🚗🚗🚗 Route created successfully ')})}catch{
            log('Wrong text format, please check format')}}}else{
        const routerArr = await routerConfig(nameFile)
        // If not
        fs.writeFile(toFileName, `${start} The ${JSON.stringify(routerArr)}`.(err) = > {
          log('🚗🚗🚗 Route created successfully ')}}}Copy the code

Detailed code

const inquirer = require("inquirer");
const { resolve } = require("path");
const fs = require("fs");const { log } = require(".. /api"); 

const filePath = 'config/routesChildren.ts'


module.exports = async (name) => {
  console.log("path", resolve("."));
  create(name)
};

async function create(nameFile){
  const desc = resolve(`. /${filePath}`);
  const isFile = fs.existsSync(desc)
  const toFileName = resolve(__dirname, desc);

  / / write
  const start = `export default`

  if(isFile){
    fs.readFile(toFileName, 'utf8'.async (err, data) => {
      try{
        const arr = JSON.parse(data.substring(14, data.length).trim())
        const routerArr = await routerConfig(nameFile)
        const res = [...arr, ...routerArr]

        fs.writeFile(toFileName, `${start} The ${JSON.stringify(res)}`.(err) = > {
          log('🚗🚗🚗 Route created successfully ')})}catch{
        log('Wrong text format, please check format')}}}else{
    const routerArr = await routerConfig(nameFile)
    // If not
    fs.writeFile(toFileName, `${start} The ${JSON.stringify(routerArr)}`.(err) = > {
      log('🚗🚗🚗 Route created successfully ')}}}async function routerConfig(nameFile){
  const name = await inquirer.prompt([{
    type: 'input'.message: 'Please set route name'.name: 'name',}])console.log("answer", name.name);
  const icon = await inquirer.prompt([{
    type: 'input'.message: 'Please set icon name'.name: 'name'.default: 'FireOutlined'
  }])
  console.log("answer", icon.name);

  return[{path: ` /${nameFile}`.name: name.name,
      icon: icon.name,
      component: `. /${nameFile}`,}}]Copy the code

Implementation effect

discuss

This chapter explains how to use the CLI to create a page. Of course, this function is not only to create a page, but also to create some common templates in a project. This method can be created in a few seconds.

Welcome everyone to leave a message for discussion, and attach the code address for everyone to visit, if it is helpful, give a small Star, support ~~

Git address: domesy- CLI

Other good posts:

  • Create your own CLI in 10 minutes
  • Build the React mobile framework out of the box
  • Build your Own Ant Design Pro V5
  • Some common Dom operations that can be easily obtained with a single Hook?