node uses command line interaction to generate corresponding templates

Posted by ben2k8 on Wed, 16 Oct 2019 16:24:43 +0200

  • Creation time: October 15, 2019
  • Test environment: win10 node-v10.16.1

Inspired by the Vue cli initialization project, I want to explore its principle and implement a similar method to create a common template block in the project.

There are three ways to achieve this

  1. readline of node
  2. Using process to implement
  3. Third party package inquirer

There are other implementation methods, such as commander.js, which are not implemented here.

Complete code for all implementations github link

The linked file structure is as follows

|--generatorTemplate.js (generate template)
|--Readline.js (complete code of readLine mode)
|--Process.js (complete code of process mode)
|--Inquirer.js (complete code of inquirer mode)

Example of template created: according to different user input, different results are returned, including the realization of generating a folder. The contents of the folder are as follows

|--template
   |--css
   |--images
   |--js
     |-- index.js

readline implementation

Introduce readline of node

const readline = require('readline');

Initial creation

const rl = readline.createInterface({
    /* Listen to readable streams */
    input: process.stdin,
    /* Read write writable stream */
    output: process.stdout,
    /* Prompt information */ 
    // prompt: 'please enter:'
});

You'll always listen to the user's input and create a template when you type template.

rl.on('line', function(input) {
    if(input === 'template') {
        /* The generator method here is shown below */
        generatorTemplate.generator()
        rl.close()
    } else if (input === 'pause') {
        rl.pause()
    } else {
        rl.write('please input right: ');
    }
})

See readline.js for the complete code

For more usage: Official document readline

Using process to implement

Generate a template when the user's input is template

const processFn = () => {
    const handleInput = (input) => {
        if(input === 'student') {
            process.stdout.write('there is student here: hew\n')
        } else if(input === 'template') {
            /* The generator method here is shown in */
            generatorTemplate.generator()
            process.stdin.emit('end');
        } else {
            process.stdout.write('some other input message\n')
            process.stdin.emit('end');
        }
    }
    process.stdin.setEncoding('utf-8')
    process.stdin.on('readable', () => {
        let chunk = null;
        while ((chunk = process.stdin.read()) !== null) {         
            if (typeof chunk === 'string') {
                chunk = chunk.slice(0, -2);
                if(chunk) {
                    handleInput(chunk)
                } else {
                    process.stdin.emit('end');
                }
            }
        }
    })
    process.stdin.on('end', () => {
        process.stdout.write('End\n');
        process.exit()
    })
}

See process.js for the complete code

For more usage: Official document process

Using inquirer

inquirer
    .prompt([
        {
            type: 'confirm',
            name: 'toBeDelivered',
            message: 'Generate template or not?',
            default: false
        },
        {
            type: 'checkbox',
            name: 'choices',
            message: 'Is this for delivery?',
            default: 'check',
            choices: ['yes', 'no']
        }
    ])
    .then(answers => {
        console.log(answers);
        /* The output value is: {tobedelivered: true, choices: ['name ']} */
        if(answers.toBeDelivered && answers.choices[0] === 'yes') {
            /* The generator method here is shown below */
            generatorTemplate.generator();
        } else {
            console.log('Do not generate template');
        }
    });

For the complete code, see inquirer.js.

For more usage: Official document inquirer

Called build template method (generator method)

generator.js

const fs = require('fs');
const path = require('path');

const jsStr = 
`const a = '';
const b = 1;
export default {
    a: a,
    b: b
}
`

function generator() {
    fs.mkdirSync(path.join(__dirname, 'template'));
    fs.mkdirSync(path.join(__dirname, 'template', 'css'));
    fs.mkdirSync(path.join(__dirname, 'template', 'js'));
    fs.mkdirSync(path.join(__dirname, 'template', 'images'));
    
    fs.writeFileSync(path.join(__dirname, 'template', 'js', 'index.js'), jsStr, 'utf-8')
}

exports.generator = generator;

Welcome to exchange Github

Topics: node.js github Vue