记录关于自己实现的一个vue脚手架

两种目录结构,一个为H5多页面 , 一个为单页面项目(后台系统) 

npm: npm i -g mch-vue-cli(安装命令) 使用

目录结构:

(后台系统)     (H5)

目的:

因为调用接口是通过vuex来调用的 而每次一个模块需要去新建一次 很麻烦,希望一个命令自动生成 所以想到用vue脚手架的形式去生成页面模块或者接口案例

简单介绍项目:

H5是想到是用多个html形式,以多页面的形式打包 (由于公司会有很多小的H5页面,自己又不想重新去搭建一个架子,怪麻烦的,所以自己想以多个html形式搭建,就不会存在这样的问题了),两个项目都是以ts为基础,这里展示一下接口的调用:

自己项目的脚手架cli代码:

啰里啰唆了半天,该说说怎么去实现自己的想法, 查了很多的资料后,了解cli的大致流程就是: 

1.通过inquire去引导

2.通过用户的选择,实现不同的功能

3.选择指定的代码仓库克隆到本地(通过download-git-repo)

4.对从git上拉下来的文件进行读写文件操作,对想要修改的内容进行修改保存(包括重命名等)

记录一下会用到的依赖:

1.fs-文件读写  2.ora-加载等待 3.path-路径 4.readline-文件按行读取 5.download-git-repo-文件下载 6.commander-定义指令 7.inquirer-交互式命令行 8.chalk-修改控制台字符串的样式

cli的目录结构:

代码:

my-vue-cli:

#!/usr/bin/env node
const program = require('commander')
 
// 定义当前版本
// 定义使用方法
// 定义四个指令
program
 .version(require('../package').version)
 .usage('<command> [options]')
 .command('add', 'add a new template')
 .command('delete', 'delete a template')
 .command('init', 'generate a new project from a template')
  
// 解析命令行参数
program.parse(process.argv)

my-vue-cli-add:

#!/usr/bin/env node

// 生成模板
const { grv, grp } = require('../util/generate')
// 生成页面
const { single , multiple } = require('../util/gtdpage')
// 添加对话
const { addQA,cons } = require('../util/constants')
// 交互式命令行
const inquirer = require('inquirer')
// 修改控制台字符串的样式
const chalk = require('chalk')
// node 内置文件模块
const fs = require('fs')

inquirer.prompt(addQA)
    .then(answers => {
        for(let item of answers.type){
            const judStore = item == cons.addStore
            const judPages = item == cons.addPages
            const singPage = answers.addType == cons.singlePage
            const multiPage = answers.addType == cons.multiPage
            if (judStore) {
                singPage ? grp(answers) : grv(answers)
            } else if (judPages) {
                singPage ? single(answers) : multiple(answers)
            }
        }
    })

generate.js:

// 用于改变文件内容
const fs = require('fs')
const os = require('os')
const ora = require('ora')
const path = require('path')
const readline = require('readline')
const colors = require('colors-console')
const download = require('download-git-repo')
const { cons } = require('../util/constants')
// 工具依赖
const {
    removalRepeat,
    downloads,
    spliceFiles,
    write,
    read,
    error,
} = require('./index')
// 常量全局
const dirname = path.join(path.resolve('./'))

const grv = (answer) => {
    generate(answer)
}

const grp = (answer) => {
    generate(answer)
}

const moduleCreate = (storePath, answer) => {
    return new Promise(async resolve => {
        let files = []
        const crindex = await downloads(cons.actionRepo, storePath)
        if (crindex) {
            const currStoreIndex = path.join(storePath, 'index.ts')
            const indexData = read(currStoreIndex)

            indexData.on('line', line => {
                files.push(line.replace(/\example/g, answer.name))
            })

            indexData.on('close', () => {
                write(files,currStoreIndex)
                resolve(true)
            })
        }
    })
}

const generate = async answer => {
    /**
     * @variable files 数据集合
     * @variable findModules modules 当前位置
     * @variable findVueUse vue.use 当前位置
     * @variable curr 当前读取位置
     * @variable usedModules 已有模块
     * @variable openIden 开启记录重复标识
     */
    let files = [] , findModules = -1 , findVueUse = -1,
        curr = 0, usedModules = [], openIden = false

    const dirStore = path.join(dirname , 'src/store')

    const storeIndex = path.join(dirStore, 'index.ts')
    
    const indexData = read(storeIndex)

    indexData.on('line', line => {
        const brace = line.includes(cons.closeBrace)
        const modules = line.includes(cons.modules)
        const colon = line.includes(cons.colon)
        const use = line.includes(cons.use)
        
        files.push(line)

        if(use) findVueUse = curr
        if(modules && colon)(findModules = curr, openIden = true)

        /**
         * @judgement curr > findModules 当前读取的位置大于标记modules的位置时开始判断
         * @judgement findModules != -1 标记不为初始值时
         * @judgement openIden 标记是否打开过
        */
        if (curr > findModules && findModules != -1 && openIden) {
            if(!brace && line != '') usedModules.push(line.trim())
            else openIden = false
        }

        curr ++
    })

    indexData.on('close' , async () => {
        const isRepeat = removalRepeat(usedModules , answer.name)
        const storePath = path.join(path.resolve('./src/store'), answer.name)
        spliceFiles(files, answer , {findModules,findVueUse})
        if(!isRepeat){
            const currtModule = await moduleCreate(storePath, answer)
            currtModule ? write(files, storeIndex) : null
        }else error('--------当前模块已重复--------')
    })
}

module.exports = {
    grv,
    grp
}

constants.js:

const initQA = [{
    type: 'input',
    message: "请输入当前模板名字:",
    name: "file",
    default: "example"
},{
    type: "confirm",
    message: "是否需要初始化默认调用接口方式:",
    name: "api",
    default: true
}]

const addQA = [{
    type: 'checkbox',
    message: '请选择项目类型:',
    name: 'type',
    choices: [
        "添加store",
        "添加页面"
    ],
    default: ['添加store'],
    validate: data => {
        if(data != '') return true;
        return "请选择添加类型";
    }
},{
    type: 'list',
    message: '请选择添加类型:',
    name: 'addType',
    choices: [
        "多页面",
        "单页面"
    ]
},{
    type: 'input',
    message: "请输入需要添加模块的名字:",
    name: "name",
    default: "example"
}]

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值