ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

处理 vue2 + vite 项目 里面的require(...+变量+...) 函数

2022-02-25 15:34:54  阅读:418  来源: 互联网

标签:index code const ...+ require item +... id


目前 vite 还不是很成熟,因为他的启动速度快,以至于我们想在开发环境使用它,生产还是继续使用webpack,也就是vite + webpack 共存的情况下:

vite 有个插件  vite-plugin-dynamic-import  会自动把  require()  函数转化为  import ...from  的方式,但是有一种情况他忽略了,就是 require() 函数里面的路径是变量拼成的,例如   require("../../assets/img/" + _vm.filePath + ".png")  ,这种情况,它就是没有处理的,所以我们自己写一个插件来解决这个问题

1. 插件定义

const path = require('path')
const glob = require('glob')
export const replaceRequireVariable = (includes = []) => {
  return {
    name: 'replaceRequireVariable',
    apply: 'serve',
    transform(code, id) {
      let result = code
      if (includes.some(item => id.includes(item))) {
        result = replaceRequrieDynamic(code, id)
      }
      return result
    }
  }
}

/**
 * 替换包含变量的require函数
 * @param {*} code
 * @param {*} id
 * @returns
 */
const replaceRequrieDynamic = function(code, id) {
  // node_modules排除
  if (/\/node_modules\//g.test(id)) return code

  const regex = /require\(\(\s*(["].*["])\s*\)\)/g
  const requireMatches = code.matchAll(regex)
  let importString = ''
  let constObjString = ''
  for (const item of requireMatches) {
    /**
     * item[0] 匹配出来的选项 例如:require(("../../assets/img/" + _vm.filePath + ".png"))
     * item[1] 匹配出来的路径 例如:"../../assets/img/" + _vm.filePath + ".png"
     *  */
    const arr = item[1].split('+')
    // 组装获取文件夹下边文件的全部路径
    let allFilePath = ''
    arr.forEach((itemStr, index) => {
      // 去除”和多余的空格
      itemStr = itemStr.replace(/"/g, '').trim()
      if (index === 0) {
        const lastIndex = itemStr.lastIndexOf('/')
        allFilePath = insertStr(itemStr, lastIndex + 1, '**/')
      } else if (index === arr.length - 1 && itemStr.startsWith('.')) {
        allFilePath += itemStr
      } else {
        allFilePath += '*'
      }
    })
    // 获取最后一个/的位置
    const lastIndex = id.lastIndexOf('/')
    // 获取Id最后一个/之前的全路径
    const absoluteDir = id.substr(0, lastIndex + 1)
    // 根绝id的全路径和相对路径获取要去获取文件的全路径
    // /mnt/c/Users/yangyanhui/projects/huiyan-manage-static/src/assets/img/**/icon_*.png
    const readAbsoluteDir = path.join(absoluteDir, allFilePath)

    // 拿到所有的指定文件
    const allFile = glob.sync(readAbsoluteDir)
    const fileObj = `_$_file_obj_${randomString(6)}`
    let fileObjectStr = ''
    if (allFile.length) {
      // 拼接文件常量
      fileObjectStr = `const ${fileObj} = {`
      allFile.forEach((file, index) => {
        // 获取引入文件的相对路径
        const relativePath = path.relative(absoluteDir, file)
        const tempFile = `_$_img_${randomString(6)}`
        fileObjectStr += `'${relativePath}': ${tempFile},`
        if (index === allFile.length - 1) fileObjectStr += '}'

        importString += `import ${tempFile} from '${file}';\n`
      })

      constObjString += `${fileObjectStr};\n`
      // require(("../../assets/img/" + _vm.filePath + ".png")) 用 fileObj 对象替换
      code = code.replace(item[0], `${fileObj}[${item[1]}]`)
    }
  }

  code = importString + constObjString + code
  return code
}
/**
 *
 * @param {必填,数字} length
 * @returns hash串
 */
function randomString(length) {
  const code = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'
  let result = ''
  for (let index = 0; index < length; index++) {
    result += code[Math.floor(Math.random() * code.length)]
  }
  return result
}

function insertStr(source, start, newStr) {
  return source.slice(0, start) + newStr + source.slice(start)
}

2. 使用插件

import { replaceRequireVariable } from './plugins.js'

export default defineConfig({
  plugins: [
    replaceRequireVariable(['hyFileStyle.vue?vue&type=template&lang.js']) // 替换 组件里面require加变量的内容
  ],
})

转发请注明出处。

 

标签:index,code,const,...+,require,item,+...,id
来源: https://www.cnblogs.com/yyh1/p/15936244.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有