哦屋~你也能夠擁有一個本身牛逼的腳手架!

技術點

  • nodejs
  • commander模塊(命令行參數處理模塊)
  • co 模塊(異步流程控制模塊)
  • co-prompt 模塊(消息提示模塊)
  • chalk 模塊(輸出字體顏色模塊)
  • github (遠程託管倉庫)
  • download-git-repo(獲取github上項目)
  • ora(loading效果,各類小圖標)

新建文件夾owu,生成package.json文件

npm init
複製代碼

安裝以上提到的模塊

npm install co co-prompt chalk commander download-git-repo ora --save-dev
複製代碼

在package.json中配置bin

"bin": {
    "owu": "bin/owu"
  }
複製代碼

編寫入口文件bin/owu

#!/usr/bin/env node
let program = require('commander');
let package = require('../package.json');
let init = require('./init');
let list = require('./list')
program
    .version(package.version)
    .usage('<command> [options]');
program.command('init (template)')
    .description("建立新項目")
    .alias('i')
    .action(function(template){
         init(template);
    })
program.command('list')
    .description("顯示可以使用的模板列表")
    .alias('l')
    .action(function(){
       list();
    })
program.parse(process.argv);
if(program.args.length==0){
    //這裏是處理默認沒有輸入參數或者命令的時候,顯示help信息
    program.help();
}
複製代碼

這個時候能夠查看初始化效果

node bin/owu
複製代碼

以上入口文件已寫好,接着能夠寫list和init命令效果

bin/list.jscss

let co = require('co');
let prompt = require('co-prompt');
let chalk = require('chalk');
let templates = require("../templates.js");
module.exports = function(){
    for(let key in templates.list){
        let temp = templates.list[key]
        console.log(
        ' ' + chalk.green('★') +
        ' ' + chalk.green(temp.name) +
        ' -' + temp.desc)
    };
    if(!templates.list||templates.list.length==0){
        console.log(chalk.yellow('當前無可用模板'))
    }
}
複製代碼

templates.jsvue

module.exports = {
    list:[
       {
        "name":"webpack",
        "path":"vuejs-templates/webpack",
        "desc":"A full-featured Webpack + vue-loader setup with hot reload, linting, testing & css extraction."
      },{
        "name":"webpack-simple",
        "path":"vuejs-templates/webpack-simple",
        "desc":"A simple Webpack + vue-loader setup for quick prototyping."
      },{
        "name":"webpack-multi",
        "path":"bluefox1688/vue-cli-multi-page",
        "desc":"支持多頁面編譯的vue模板"
      }
    ]
}
複製代碼

查看模版效果

node bin/owu list
複製代碼

bin/init.jsnode

let co = require('co');
let prompt = require('co-prompt');
let chalk = require('chalk');
let templates = require("../templates");
let download = require('download-git-repo');
let ora = require('ora');
let fs  = require('fs');
let utils = require('./utils');
let temps = {};
let temps2 = {};
module.exports = function(name) {
    getTemps(templates);
    co(generator(name));
}

function getTemps(templates) {
    for(let key in templates.list) {
        let item = templates.list[key]
        temps[key] = item.name;
        temps2[item.name] = item.path;
    };
}

let generator = function *(name) {
        let tempName  = name;
        let path = temps2[name];
        if(typeof tempName !== 'string') {
           console.log(' 可用模板列表:')
           for(let key in temps) {
                let tempName = temps[key]
                console.log(
                    ' ' + chalk.green(key) +
                    ' : ' + chalk.green(tempName))
                };
               tempName = yield prompt(" 請選擇模板類型:")
               path = temps2[temps[tempName]];
        }
        if(temps[tempName] || temps2[tempName]) {
                console.log(' ----------------------------------------')
                let projectName = yield prompt(" 請輸入項目名稱(demo):")
                if(!projectName) {
                    projectName = "demo"
                }
                console.log(' ----------------------------------------')
                downloadTemplates(path,projectName);

        } else {
                console.log(chalk.red(` ✘模版[${tempName}]不存在`))
                process.exit(0);
        }
    }

function downloadTemplates(path,projectName) {
        let spanner = ora(" 正在構建,客官請稍等......");
        spanner.start();
        if(fs.existsSync('download')){
            //刪除原文件
            utils.rmdirSync('download');
        }
        download(path,__dirname+'/download', function(err) {            
                if(err) {
                    spanner.stop();
                    console.log(' ','----------------------------------------')
                    console.log(' ',chalk('x構建失敗'), err);
                    process.exit(0);
                }
                startBuildProject(spanner,projectName)
        })

    }

function startBuildProject(spanner,projectName){
    let targetPath = process.cwd()+"/"+projectName
    utils.copyDirSync(__dirname+'/download',targetPath)
    console.log(' ','----------------------------------------')
    console.log(' ',chalk.green('★'),chalk.green('項目構建成功'));
    spanner.stop();
    process.exit(0);
}
複製代碼

bin/utils.jswebpack

const fs = require('fs');

// 刪除文件
function rmdirSync(path){
  let files = [];
  if(fs.existsSync(path)){
      files = fs.readdirSync(path);
      files.forEach((file, index) => {
          let curPath = path + "/" + file;
          if(fs.statSync(curPath).isDirectory()){
              rmdirSync(curPath); //遞歸刪除文件夾
          } else {
              fs.unlinkSync(curPath); //刪除文件
          }
      });
      fs.rmdirSync(path);
  }
}

// 複製文件
function copyDirSync(from,to){
  let files = [];
    if (fs.existsSync(to)) {           // 文件是否存在 若是不存在則建立
        files = fs.readdirSync(from);
        files.forEach(function (file, index) {
            var targetPath = from + "/" + file;
            var toPath = to + '/' + file;
            if (fs.statSync(targetPath).isDirectory()) { // 複製文件夾
              copyDirSync(targetPath, toPath);
            } else {                                    // 拷貝文件
                fs.copyFileSync(targetPath, toPath);
            }
        });
    } else {
        fs.mkdirSync(to);
        copyDirSync(from, to);
    }
}

module.exports = {
  rmdirSync,
  copyDirSync
}
複製代碼

初始化項目

node bin/owu init webpack
複製代碼

將命令提高到全局

npm link
複製代碼

最後能夠試試這些命令

owu #查看配置
複製代碼
owu init #初始化項目
複製代碼
owu init webpack #初始化項目,使用webpack模版
複製代碼
owu list #查看模版列表
複製代碼
owu --help #幫助
複製代碼
相關文章
相關標籤/搜索