Results show

  • Use the COMMANDER imperative effect

  • Use inquirer interactive effects

Initialization operation

  • usenpm init -yCommand to quickly generate package.json files
  • On the setnamemainThe value of the
  • You need to add the bin configuration item; otherwise, the global command may be invalid.binFields: Commands that you can customize the scaffold tool, such as the followingmycliAnd themycliThe command execution script follows.
{
  "name": "mycli"."version": "1.0.0"."description": ""."main": "index.js"."scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "bin": {
    "mycli": "bin/index.js"
  },
  "keywords": []."author": ""."license": "ISC"
}
Copy the code
  • createindex.jsFile, enter the content#! /usr/bin/env nodeSpecifies to run in the Node environment
#! /usr/bin/env node
#!/usr/bin/env node console.log('hello mycli! ')
Copy the code
  • Using the NPM link command to create a global module will automatically generate /node_modules/mycli/index.js under the global node variable, and you can debug the scaffolding tool locally

  • NPM install chalk shelljs inquirer –save

    • chalk— is a node output log style library
    • shelljsA library for executing shell commands
    • inquirerInteractive command library

The directory structure

- mycli 
    - node_modules 
    - template 
        - vue 
            - vue.html 
        - h5 
            - h5.html
        ...
    - createProject.js 
    - index.js 
    - package.json
Copy the code
  • node_modulesScaffolding is needed to rely on
  • templateThis directory stores the templates required by the CLI, and the final project generated by users using scaffolding is copied from this directory
  • createProject.jsThe code to pull the project is all here
  • index.jsScaffold entry document
  • package.jsonDescription of projects and modules

Specific code

  • index.js
    #!/usr/bin/env node
    let program = require('commander')
    let createProject = require('./createProject')

    // To set the version number and parameters, run mycli --help
    program.version('1.0.0')
        .option('-t, --type <name>'.'project type')
        .option('-n, --type <name>'.'project type')

    // Capture commands and parameters eg: mycli create test -t vue
    program
        .command('create <name>')
        .action(function(name) {
            createProject(name, program.type)
        })

    program.parse(process.argv)
Copy the code
  • createProject.js
    let chalk = require('chalk'); // Node terminal style library
    let fs = require('fs');
    let path = require('path');
    let inquirer = require('inquirer');

    require('shelljs/global'); // Execute the shell script

    let log = function(txt) {
        console.log(chalk.green.bold(txt))
    }

    async function createProject(name, type) {
        let p = process.cwd() // Get the current path
        cd(p) // shell cd

        // Check whether the folder exists. If so, delete it and install it
        if(fs.existsSync(name)) {
            log('project exists, please rename it');
            var questions = [
                {
                type: 'confirm'.name: 'isRemoveDir'.message: `delete ${name}? `.default: false,}]const answer = await inquirer.prompt(questions).then((answers) = > {
                return answers
            });

            if(! answer.isRemoveDir) { process.exit(); } rm('-rf', name); // shell rm 
            log(`delete ${name} success`)}let np = path.join(__dirname, 'template', type);
        cp('-R', np+'/', name) // shell cp
        log(` pull '${type}'Project successful! `)
        
        cd(name) // shell cd
        log('set up taobao image source - NPM config set registry http://registry.npm.taobao.org')
        exec('npm config set registry http://registry.npm.taobao.org') / / perform custom shell command NPM config set registry at http://registry.npm.taobao.org
        log('NPM install')
        log('In the installation module... ')
        log('The installation may take a long time, please be patient, you can also stop the installation by pressing CTRL + C and manually NPM install')
        exec('npm install') // Run the custom shell command NPM install

        // The logic here is custom, according to the requirements of their own
        if(type ! ='jquery') {
            log('Starting project')
            exec('npm start') // Run the custom shell command NPM start
        }

        log('Scaffold initialization completed')
        process.exit() 

    }

    module.exports = createProject
Copy the code

use

  • mycli --help–help is the built-in commander command, which can output scaffolding commands
  • mycli create demo -t vueThis is our custom command to create a demo folder with Vue as the template

Project reform

The Commander command was too cumbersome to use and the parameters were too hard to remember, so we used Inquirer to transform into a full-on interactive scaffolding

  • Modify theindex.js
    #!/usr/bin/env node
    const createProject = require('./createProject')
    const inquirer = require('inquirer');
    const fs = require('fs');
    const path = require('path');

    const promptList = [
        {
            type: 'input'.message: 'Please enter a project name'.name: 'name'.default: 'my-project'}, {type: 'list'.message: 'Please select project type'.name: 'type'.choices: fs.readdirSync(path.join(__dirname,'template')) // Read the list of directories under the tempate directory through the fs module
        }
    ]

    inquirer.prompt(promptList).then((answers) = > {
        createProject(answers.name, answers.type)
    });
Copy the code
  • Start the commandmycli, do not remember tedious parameter options, directly through the prompt operation

conclusion

Custom scaffolding relies on the Node environment for file manipulation through the FS module provided by Node. NPM also provides a variety of command libraries (Commander, Shelljs) and interactive libraries (Inquirer) for our convenience, and our main operation is to provide our own scaffold templates