简易前端脚手架的搭建

脚手架流程图 : 

 

脚手架技术实现文档

一、初期准备工作:

1.1.新建项目并初始化  npm init

 

1.2.安装依赖:
    1. commander:添加命令、完善命令处理逻辑
    2. inquirer:交互式获取用户指令
    3. chalk:添加颜色样式,代码不再单调
    4. fs-extra:覆盖旧有文件夹
    5. download-git-repo:下载gitlab/github代码
    6. glob:操作目录
    7. ora:下载进度条

 

1.3.挂载命令(本地调试使用): npm link ,卸载则是npm unlink

二、主要的实现代码:

 
## 项目结构
    |- bin  执行入口目录
        |- enter.js 入口文件,初始化相关指令对应逻辑
    |- lib  交互式命令对应执行目录
        |- create.js 模板创建文件,命令的详细执行逻辑
        |- download.js 下载文件配置
        |- inquirerChoise.js 百望云、运营侧的特有可配置信息
        |- maually.js 手动配置实现函数
    |-presetsCommon 公共预置信息
        |-api 公共接口请求
        |-components 公共组件
        |-utils 字典相关维护
        |-uiComponets 公共ui组件
    |-presetsCloud  百望云预置信息
        |-api 特有接口请求
        |-components 特有组件
        |-utils 特有字典相关维护
        |-uiComponets 特有ui组件
        |-store vuex仓库
    |-presetsZeus  运营后台预置信息

2.1.bin文件夹下的入口文件enter.js

顶部代码   #! /usr/bin/env node,作用:定位命令执行的目录

 

 

2.2.create.js创建具体的创建交互效果

 

 

2.3 对于store入口文件,使用动态引入模块的方式一一自动添加,重新导出各个模块的导出内容,此处可开启命名空间,支持按模块引用对应方法。

 

2.4 对于ui组件的入口文件,亦使用动态引入的方式进行添加,重新导出各个模块的导出内容

 

2.5.手动配置的实现过程:

  1. 提出公共部分至工具包的presets文件夹;
  2. 创建一个全局变量的文件获取交互窗口中用户选择的内容;
  1.使用path的join获取待写入的文件地址
  2.使用fs的readFileSync方法读取文件的内容
  3.将内容转换为数组,将数组中的元素转为key-value的键值对对象
  4.遍历此对象,与用户选择内容进行比对,设置其变量值
  5.将修改后的内容重新写入此文件更新内容

   3.根据不同的变量使用不同的配置函数,注入至模板内;

let {
                            Introduce_Components_Needed: icd,
                            Introduce_Autoplugins: ia,
                            Introduce_Leftmenu: il,
                            Introduce_MultiTabbed: im,
                            Introduce_Dictionary: id,
                            Scss_Variable: sv,
                            Introduce_OrgTree: io,
                            Iframe_Listen_Methods: ilm,
                            SearchAndTable: sat,
                            Global_Introduce_Components: gic,
                            Header_Components: hc
                        } = envVariables

                        if (icd === 'true') {
                            // 按需引入bw-design组件
                            addComponents(targetDir)
                        }

                        if (ia === 'true') {
                            // 引入autoplugins
                            addAutoplugins(targetDir)
                        }

     4.部分预设注入逻辑

// 复制文件--可覆盖
function copyFiles (sourceFile, targetFile) {
    fs.copyFile(sourceFile, targetFile, (err) => {
        if (err) {
            console.error(`复制文件 ${sourceFile} 到文件 ${targetFile} 失败`, err)
        }
    })
}

// 复制文件夹
function copyFloders (source, target) {
    // 如果目标文件夹不存在,则创建
    if (!fs.existsSync(target)) {
        fs.mkdirSync(target, { recursive: true })
    }
    const files = fs.readdirSync(source)
    files.forEach((file) => {
        const currentS = path.join(source, file)
        const currentT = path.join(target, file)
        if (fs.statSync(currentS).isDirectory()) {
            copyFloders(currentS, currentT)
        } else {
            copyFiles(currentS, currentT)
        }
    })
}

// 左菜单
function addLeftmenu (targetDir) {
    const sPth = path.join(__dirname, '../presetsCloud/components/LeftMenu')
    const tPath = path.join(targetDir, 'src/components/LeftMenu')
    copyFloders(sPth, tPath)

    const sPth1 = path.join(__dirname, '../presetsCloud/components/LeftMenuContent.vue')
    const tPath1 = path.join(targetDir, 'src/pages/Content.vue')
    copyFiles(sPth1, tPath1)
}

// 添加前端预置字典 --字典涉及接口
function addDictionary (targetDir, type) {
    // 创建api文件夹--注入index
    const apiDir = path.join(targetDir, 'src/api')
    if (!fs.existsSync(apiDir)) {
        fs.mkdirSync(apiDir)
    }
    const targetFile = path.join(targetDir, 'src/api/index.js')
    copyFiles(reqInitPath, targetFile)

    // 创建methods文件夹---注入方法
    const methodsDir = path.join(targetDir, 'src/api/methods')
    if (!fs.existsSync(methodsDir)) {
        fs.mkdirSync(methodsDir)
    }
    if (type === '2') {
    // api请求方法
        const sPath = path.join(__dirname, '../presetsCloud/api/methods/_dict.js')
        const tPath = path.join(targetDir, 'src/api/methods/sysDict.js')
        copyFiles(sPath, tPath)
        // 配置转换文件
        const sPath1 = path.join(__dirname, '../presetsCommon/utils/_dictTrans.js')
        const tPath1 = path.join(targetDir, 'src/utils/dictTrans.js')
        copyFiles(sPath1, tPath1)

        // 存入vuex
        const stroreDir = path.join(targetDir, 'src/store')
        const stroreDir1 = path.join(targetDir, 'src/store/modules')
        if (!fs.existsSync(stroreDir)) {
            fs.mkdirSync(stroreDir)
        }
        if (!fs.existsSync(stroreDir1)) {
            fs.mkdirSync(stroreDir1)
        }
        const sPath2 = path.join(__dirname, '../presetsCloud/store/index.js')
        const tPath2 = path.join(targetDir, 'src/store/index.js')
        copyFiles(sPath2, tPath2)
        const sPath3 = path.join(
            __dirname,
            '../presetsCloud/store/modules/_dict.js'
        )
        const tPath3 = path.join(targetDir, 'src/store/modules/_dict.js')
        copyFiles(sPath3, tPath3)
    } else if (type === '3') {
        const sPath = path.join(__dirname, '../presetsZeus/api/methods/_dict.js')
        const tPath = path.join(targetDir, 'src/api/methods/sysDict.js')
        copyFiles(sPath, tPath)
        // 配置转换文件
        const sPath1 = path.join(__dirname, '../presetsCommon/utils/_dictTrans.js')
        const tPath1 = path.join(targetDir, 'src/utils/dictTrans.js')
        copyFiles(sPath1, tPath1)
    }
}

      5.返回最终模板文件夹。

 spinner.succeed()
                resolve(target)

 

6.下载download.js

direct方式:输入完整的gitlab/github的url(浏览器的url)+分支名

 

posted @   新时代的搬砖人  阅读(22)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示