项目被二开了,我想修改组件路径怎么办?

前端小玉儿一直喜欢解决问题,更喜欢的是帮同事处理好问题之后的成就感。多年开发中,遇到的问题很多,一直也没时间整理成文章。这周正好离开职场,时间自由了,今后可以做持续的分享或系列文章,将多年的实战经验分享给宝子们。

一、背景介绍

负责一个vue低代码平台,接手时已经被拿去进行二次开发了,里面的部分组件也被引用过了。但是,项目中某些核心组件,目录混乱,此时修改,势必会导致二次开发组件引用异常,而且,通知各组去修改组件引用路径也不现实。于是,前端小玉儿做了如下方案。废话少说,直接上干货。

二、解决方案

该解决方案的核心原理为:webpack支持配置别名,可将旧路径作为别名的key,新路径作为别名的value。

虽然原理很简单,但是在操作的过程中也遇到了种种问题。遇到的坑坑洼洼在代码备注内有所体现。而且,末尾会有个总结,供各位伙伴参考。

具体操作及代码见下文。

2.1 添加新旧路径映射

创建一个新旧路径文件目录映射关系的js文件pathMap.js,该文件返回一个json对象,其书写示例如下:

java 复制代码
module.exports = {
    'src/components/custom': 'src/views/custom'  // key 为新路径,value为旧路径
}

2.2 读取文件生成别名对象

这部分操作均在vue.config.js中完成。

2.2.1 引入依赖包

脚手架的一系列依赖中已经包含了fs-extra以及path依赖,在vue.config.js中引入这两个依赖包

javascript 复制代码
const fs = require('fs-extra')
const path = require('path')
const pathMap = require('./src/pathMap.js') // 新旧路径映射对象
const pathSep = path.sep // 不同操作系统下的路径分割符号

2.2.2 封装webpack配置别名对象获取方法

csharp 复制代码
function getTargetObj() {
    const newPathArr = Object.keys(pathMap) // 获取新路径列表
    const targetObj = {}
    for (var i = 0; i < newPathArr.length; i++) {
        const newPathKey = newPathArr[i]
        const newPath = newPathKey.split('/').join(pathSep)
        try {
            const stat = fs.statSync(newPath)
            const targetPath = fileMap[newPathKey].split('/').join(pathSep)
            if (stat.isDirectory()) { // 如果新路径是个文件夹
                readDir(newPath, targetObj, targetPath, newPath)
            } else { // 如果新路径直接是个文件
                targetObj[path.resolve(__dirname, targetPath)] = path.resolve(__dirname, newPath)
            }
        } catch (error) { // 如果新路径报错,直接是一个不带后缀的文件
            console.info('文件匹配错误信息:', '您重定向的文件路径既不是文件夹也不是带有扩展名的文件')
        }
    }
    return targetObj
}

特别注意:生成的别名对象的key值与value值必须是path.resolve(__dirname, path)的结果,否则无法使用。

2.2.3 读取文件目录的递归方法

ini 复制代码
function readDir(dirPath, configJson, oldPath, newPath) {
    const files = fs.readdirSync(dirPath)
    const result = {}
    files.forEach(function(file) {
        const newDirPath = dirPath
        const filePath = path.join(newDirPath, file)
        const stat = fs.statSync(filePath)
        if (stat.isDirectory()) { // 判断是否为文件夹
            result[file] = readDir(filePath, configJson, oldPath, newPath)
        } else {
          const oldFilePath = filePath.replace(newPath, oldPath)
          configJson[path.resolve(__dirname, oldFilePath)] = path.resolve(__dirname, filePath)
           // index.vue或index.js时需特殊处理,否则webpack无法正确重定向
          if (filePath.includes(pathSep + 'index.vue') || filePath.includes(pathSep + 'index.js')) {
              const targetStr = filePath.includes(pathSep + 'index.vue') ? pathSep + 'index.vue' : pathSep + 'index.js'
              const oldFilePath_ = oldFilePath.replace(targetStr, '')
              const newFilePath_ = filePath.replace(targetStr, '')
              configJson[path.resolve(__dirname, oldFilePath_)] = path.resolve(__dirname, newFilePath_)
          }
        }
    })
    return configJson
}

2.3 配置别名

在vue.config.js中添加webpack别名配置即可,示例代码如下:

css 复制代码
configureWebpack: {
    resolve: {
        alias: {
            '@': resolve('src'),
            ...getTargetObj()
        }
    }
}

至此,这个解决方案已经配置完毕,即使更换了组件位置,只要正确配置了新旧路径关系,运行项目就可正常加载组件。前端小玉儿也算松了口气。

三、遇到的坑坑洼洼

  1. 别名配置中的key与value不支持直接书写路径字符串,需要使用path.resolve()后的结果
  2. 别名配置不支持直接使用文件夹的路径作为key或value,需要读取到文件级别,index.js或index.vue除外
  3. 遇到路径中存在index.vue或index.js时,需要读取到该文件的上级目录
  4. 不同操作系统下,路径的分隔符号存在差异,需要统一替换为path.sep
  5. 最重要的一点:

如果你的项目还处于萌芽阶段,可以提前配置别名指向各个文件夹的路径,引用时直接使用别名,以后如果优化目录,直接改这里就OK了,不用做映射了。

  1. 最后的最后,前端小玉儿提醒,修改一定要做好注释,否则,百年之后,优化掉了,系统瘫了,可能存在被刨坟的风险。
  2. 今天这个问题就处理到这里,宝子们觉得有用,辛苦您的小手点个赞,有问题也可以随时联系爱解决问题的前端小玉儿。
相关推荐
Calm55014 分钟前
Vue3:uv-upload图片上传
前端·vue.js
新中地GIS开发老师27 分钟前
《Vue进阶教程》(12)ref的实现详细教程
前端·javascript·vue.js·arcgis·前端框架·地理信息科学·地信
漫天转悠27 分钟前
Vue3中404页面捕获(图文详情)
vue.js
Cachel wood1 小时前
Django REST framework (DRF)中的api_view和APIView权限控制
javascript·vue.js·后端·python·ui·django·前端框架
天天进步20152 小时前
Vue项目重构实践:如何构建可维护的企业级应用
前端·vue.js·重构
2402_857583492 小时前
“协同过滤技术实战”:网上书城系统的设计与实现
java·开发语言·vue.js·科技·mfc
小华同学ai2 小时前
vue-office:Star 4.2k,款支持多种Office文件预览的Vue组件库,一站式Office文件预览方案,真心不错
前端·javascript·vue.js·开源·github·office
k09333 小时前
vue中proxy代理配置(测试一)
前端·javascript·vue.js
@解忧杂货铺8 小时前
前端vue如何实现数字框中通过鼠标滚轮上下滚动增减数字
前端·javascript·vue.js
苹果酱056710 小时前
「Mysql优化大师一」mysql服务性能剖析工具
java·vue.js·spring boot·mysql·课程设计