Yargs official address

In the past, every time to build a module, we had to manually create it, which was very tedious. After checking the company’s project, we found that Yargs was used for automatic creation, and we could customize commands and parameters to deal with problems. By learning YARgs, incidentally write an automatic module creation tool.

Step 1.

  • Step 1: Parameters to pass

There are three parameters
File: Folder and module name (required)
Path: indicates the file saving path
Type: indicates the template type
  • Step 2: Create a command and process the parameters passed in

     command(cmd, desc, [builder], [handler])
Creates a command using the command method and puts the previously defined parameters into the command bulider.
[handler] Processes parameter transmission.
  • Step 3: Process parameters

1. Create a folder
2. Create a file
  • Step 4: Customize the template

It's not enough to be able to create a file, we need the file content to be the template content we defined, so we define the template first.
  • Step 5: Do some experience optimization, create file prompts, repeat file prompts

2. The directory

ReactTemplat and VueTemplate are user-defined templates that can be customized based on the template content and structure.

Cli.js: used to create commands and pass parameters to the start file for processing.

Start. js: handles parameters, creates folders and files, and interacts with the user using the process process.

Handle.js: method for handling files.

3. Help information

Node./tools/cli add -h // Display help information Options: --version Show version number [Boolean] -h Showhelp                                                [boolean]
  --file, -f  create a file                                          [required]
  --path, -p  file path                                            [default: ""] - type, -t file 'stype             [choices: "vue"."react"] [default: "vue"]

Examples:
  node tools/cli add  -p views -f test-t vue Creates one in the views directorytestThe templateCopy the code

Use 4.

node tools/cli add  -f test -p views -t vue
Copy the code
Create a test module in the views directory. The module type is vue.

Check whether the directory exists when creating a module.

If duplicate modules are encountered, you can override them

Address of the file

cli.js

const argv = require('yargs')
  .command(
    'add'.'create a file'.function(yargs) {
      return yargs
        .option('file', {
          alias: 'f',
          describe: 'create a file'
        })
        .option('path', {
          alias: 'p',
          describe: 'file path',
          default: ' '
        })
        .option('type', {
          alias: 't',
          describe: 'file' s type ',
          choices: ['vue'.'react'], // Now there are two templates to choose from. You can design the template according to your own project situation.'vue'
        })
        .demandOption(['file'].'Please provide file to work with this tool')
        .example(
          'node tools/cli add -p views -f test -t vue'.'Create a test template in the views directory')},function(argv) {start(argv)}).help('h').argv

Copy the code

start.js

const handel = require('./handle')
const colors = require('colors')
const path = require('path')
module.exports = async function(argv) {
  argv.file = argv.file.toString()
  const existPathFolder = await handel.existFolder(path.resolve(argv.path))
  const fileName =
    argv.file.substring(0, 1).toUpperCase() + argv.file.substring(1)
  let className = ' '

  for (let i = 0; i < argv.file.length; i++) {
    if (/[A-Z]/.test(argv.file[i])) {
      className += The '-'
    }
    className += argv.file[i].toLowerCase()
  }
  if(argv.path ! = =' ') {
    argv.path += '/'
  }
  const filePath = path.resolve(argv.path) + '/' + fileName
  process.stdin.setEncoding('utf8')

  const createFileData = {
    filePath,
    fileName,
    className,
    type: argv.type} // There is no path folderif(! ExistPathFolder) {console.warn(colors. Green (' whether to create${path.resolve(argv.path)}Folder? : y/n `)) process. Check stdin.'data', async chunk => {
      chunk = chunk.replace(/[\s\n]/, ' ')
      if (chunk === 'y') {// Create path folder await handel.createFolder(path.resolve(argv.path)) // Create component folder await handel.createFolder(filePath) // CreateFile await handel.createfile (createFileData) process.exit()}else if (chunk === 'n') {
        process.exit()
      } else {
        console.warn(colors.red('Please enter the correct instruction: y/n'))
        process.exit()
      }
    })
  } else{// Check whether the component folder has const existFileFolder = await handel.existFolder(filePath)if (existFileFolder) {
      console.warn(colors.green(`${fileName}The folder already exists. Do you want to overwrite it? : y/n `)) process. Check stdin.'data', async chunk => {
        chunk = chunk.replace(/[\s\n]/, ' ')
        if (chunk === 'y') {// create component folder await handel.createfolder (filePath) // createFile await handel.createfile (createFileData) process.exit()}else if (chunk === 'n') {
          process.exit()
        } else {
          console.warn(colors.red('Please enter the correct instruction: y/n'))
          process.exit()
        }
      })
    } else{// create component folder await handel.createfolder (filePath) // createFile await handel.createfile (createFileData) process.exit()}}}Copy the code

handle.js

const fs = require('fs')
const colors = require('colors')
const path = require('path')
module.exports = {
  existFolder: async function(path) {// Determine whether the argv.path folder existsreturn new Promise(function(resolve, reject) {
      returnFs.exists (path, e => {resolve(e)})})}, /** * createFolder @param filePath filePath */ createFolder:function(filePath) {
    return new Promise(function(resolve, reject) {
      fs.mkdir(filePath, function(err) {
        if (err) {
          if (err.errno === -2) {
            console.log(colors.red('Directory not found'))}else if (err.errno === -17) {
          }
        } else {
          console.log(colors.green('Create folder:'))
          console.log(colors.underline(`${filePath}'))} resolve()})})}, /** * @param args:{* filePath filePath * fileName fileName * className style name *typeFile type *} */ createFile:function({ filePath, fileName, className, type}) {const data = {fileName, filePath, className}type) {
      case 'vue':
        data.templateFolderPath = path.join(__dirname, './VueTemplate')
        break
      case 'react':
        data.templateFolderPath = path.join(__dirname, './VueTemplate')
        break
      default:
        data.templateFolderPath = path.join(__dirname, './VueTemplate')}returnnew Promise(async (resolve, reject) => { await this.readAndWiteFile(data, resolve) }) }, @param args:{* templateFolderPath template path * fileName fileName * filePath filePath * className style name *} * @param resolve */readAndWiteFile: function(
    { templateFolderPath, fileName, filePath, className },
    resolve
  ) {
    fs.readdir(templateFolderPath, 'utf8', (err, files) => {
      if (err) {
        console.log(colors.red(err))
        return false
      }
      files.forEach(templateName => {
        const FileName = templateName
          .replace('TemplateName', fileName)
          .replace('.txt'.' 'Create file fs.createWritestream ('${filePath}/${FileName}Const content = fs.readfilesync (') // 2${templateFolderPath}/${templateName}').tostring () // Reads the template file.replace(/\${TemplateName}/g, FileName.split('. ')[0])
          .replace(/\${template-name}/g, className) // Replace templateName with the corresponding file name fs.writefilesync ('${filePath}/${FileName}`, content, 'utf8')

        console.log(colors.green('Write file:'))
        console.log(colors.underline(`${filePath}/${FileName}`))
      })

      resolve()
    })
  }
}
Copy the code

This method is cumbersome, and two versions are optimized below

1. You do not need to enter the handwritten path and type

(1) Node tools2/cli add -f fileName

(2) Prompt to select template

(3) Select the placement position to provide access to the next layer and return to the operation of the upper layer

2. You do not need to select paths layer by layer

Once the deep path appears above, the operation will be very tedious. Therefore, dynamic path selection is provided, and the path address is prompted according to the keyword.

steps

(1) Node tools3/ CLI

(2) Enter the file name

(3) Prompt to select template

(4) Prompt to place the address