• 创建时间:2019-10-15
  • 测试环境:win10 node-v10.16.1

vue-cli 初始化项目的启发,想探究其原理和自己实现一套类似方法,以便在项目中创建公用模板块。


这里采用三种方式实现

  1. node 自带的 readline
  2. 使用process实现
  3. 第三方包 inquirer

还有其它实现方式如 commander.js 等,这里不做具体实现

所有实现方式的完整代码 github 链接

链接文件结构如下

|-- generatorTemplate.js (生成模板)|-- readline.js (readline 方式完整代码)|-- process.js (process 方式完整代码)|-- inquirer.js (inquirer 方式完整代码)

创建的模板示例:根据用户输入的不同,返回不同结果,包括实现了生成一个文件夹,文件夹内容如下

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

readline 实现

引入 node 自带的 readline

const readline = require('readline');

初始创建

const rl = readline.createInterface({    /* 监听可读流 */    input: process.stdin,    /* 读取写入的 可写流 */    output: process.stdout,    /* 提示信息 */     // prompt: '请输入:'});

这里会一直监听用户的输入 当输入template时 创建模板

rl.on('line', function(input) {    if(input === 'template') {        /* 这里的generator方法参见下方 */        generatorTemplate.generator()        rl.close()    } else if (input === 'pause') {        rl.pause()    } else {        rl.write('please input right: ');    }})

完整代码查看 readline.js

更多用法参考: 官方文档 readline

使用process实现

当用户输入的内容为template时,就生成模板

const processFn = () => {    const handleInput = (input) => {        if(input === 'student') {            process.stdout.write('there is student here: hew\n')        } else if(input === 'template') {            /* 这里的generator方法参见 */            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('结束\n');        process.exit()    })}

完整代码查看 process.js

更多用法参考: 官方文档 process

使用 inquirer

inquirer    .prompt([        {            type: 'confirm',            name: 'toBeDelivered',            message: '是否生成模板?',            default: false        },        {            type: 'checkbox',            name: 'choices',            message: 'Is this for delivery?',            default: 'check',            choices: ['yes', 'no']        }    ])    .then(answers => {        console.log(answers);        /* 输出值为:{ toBeDelivered: true, choices: [ 'name' ] } */        if(answers.toBeDelivered && answers.choices[0] === 'yes') {            /* 这里的generator方法参见下方 */            generatorTemplate.generator();        } else {            console.log('不生成模板');        }    });

完整代码查看 inquirer.js

更多用法参考: 官方文档 inquirer

调用的生成模板方法 (generator 方法)

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;
欢迎交流 Github