基于node批量上传图片cdn并且替换本地地址

最近有个优化是为了减少app的bundle包大小,写了个node脚本用于图片cdn化,有这方面需求的小伙伴阔以康康


以下举例的开发语言为react-native cdn是七牛 小伙伴根据自己的情况自行摘取 图片为.webp格式

需求:本地大量图片导致app的bundleSize过大 以至于想把本地的图片都上传到cdn,并且把对应上传cdn的资源路径替换掉本地require的引用方式

需求直观demo

   本地代码引用块:

source={require('../../xx/images/xx/xx.webp')}

  替换后的代码块:

source={{uri: 'https://xx.come/xx.webp'}}

以上就直观展示了需要实现的功能


各位看官 那我就开始划水了~ 啊忒   您就看我细听分说

那我们就来说道说道这 配置篇 

话说我用cdn是七牛 既然要上传 各位客官不妨把配置搞一搞 

当然 npm install qiniu --save这一步骤可少不了

这是在下列的配置清单 各位客官自行摘取(搬运~我们都是代码的搬运工)

const qiniu = require('qiniu')

//  七牛配置
  let config = {}
  config.accessKey = 'xxx';
  config.secretKey = 'xxx';
  config.bucket = 'xxx';  //存储空间的名字
  config.url = 'xxx';  //配置的域名

//  获取七牛上传token)
  const putPolicy = new qiniu.rs.PutPolicy({ scope: config.bucket });
  const mac = new qiniu.auth.digest.Mac(config.accessKey, config.secretKey);
  const uploadToken=putPolicy.uploadToken(mac);

//  上传配置
  const newConfig = new qiniu.conf.Config();
  newConfig.zone = qiniu.zone.Zone_z2
  const localFile = xxxx //  本地文件路径
  const formUploader = new qiniu.form_up.FormUploader(newConfig) //  生成表单上传的类
  const putExtra = new qiniu.form_up.PutExtra() //  生成表单提交额外参数
  const key ='按自己需求或者规则来命名 尤其是批量 要考虑防止命名污染' //  重命名文件

关于这个newConfig.zone我可得好好说道说道

关于这个区域 各位看官根据自己条件配置 

具体内容各位看官可以挪步:https://developer.qiniu.com/kodo/manual/1671/region-endpoint

看完以上配置以后是不是就差一个重要的配置项key 也就是获取到要上传的图片路径我们就可以上菜了 刚把得


路径篇 各位看官一定要用同步读取写入 不要用异步 防止后续写入的坑

当然 为了读取文件/目录 node提供的fs模块 不得不说 方便的一逼啊

//  获取要上传的图片路径
getImagePath = src => {
  const files = fs.readdirSync(src)
  files.forEach((file) => {
    const _src = `${src}/${file}`
    fs.stat(_src, (err,stats)=> {
      if (err) {
        throw err
      }
      //  判断为文件
      if (stats.isFile()) {
        //  读取.webp后缀文件
        if (file.includes('.webp')) {
          uploadImg(_src,file) 
        }
      } else if (stats.isDirectory()){
        getImagePath(_src)
      }
    })
  })
}

我jio得就不要用过于介绍这个了把 相关api方法随便搜一下Node方法 脱裤子都比我快

其实就是给到该方法一个你要去操作的路径 该方法递归查询每个目录下的每个文件 确保找到.webp格式的图片路径

拿到对应的webp格式图片的路径 我们要干嘛 对 刚它

//  图片上传
  formUploader.putFile(uploadToken, key, localFile, putExtra, (respErr, respBody, respInfo)  => {
    if (respErr) {
      console.log('上传失败----' + respErr)
      throw respErr
    }
    //  上传成功
    if (respInfo.statusCode == 200) {
        console.log('上传成功---' + fileName)
        xxFunction(fileName, pathName)
    } else {
      console.log('上传失败----')
      console.log(respInfo.statusCode)
      console.log(respBody)
    }
  })

你看这个方法它又大又圆 就像这个面它又长又宽

~~~言归正传 这个方法的入参 从上到下我们是不是就齐活了 对于你传入一个你想上传的路径 啥事你都不要管 就等命令行的 上传成功

到这里 就算再不舍 我也得说再见 ~~~~~ 哎?不对 你说好的替换呢 

来了来了

//  获取 .tsx || .ts 文件中需要替换的require地址
getFileImageUrl = (fileName,callBackUrl) => {
  const replacePath = callBackUrl || fileReplacePatch  //  指定替换的目录 
  //  读取目录/文件
  var files = fs.readdirSync(replacePath)
  files.forEach((file) => {
    const _src = `${replacePath}/${file}`
    fs.stat(_src, (err,stats)=> {
      if (err) {
        throw err
      }
      //  判断为文件
      if (stats.isFile()) {
        //  读取.tsx .ts后缀文件
        if (file.includes('.tsx') || file.includes('.ts')) {
          //  读取文件信息
          var data = fs.readFileSync(_src)
          data = data.toString()
          const reg = /(?<=require).*?(?=(.webp|$))/g
          const arr = data.match(reg)
          if (arr) {
            try {
              arr.forEach((f) => {
                let requestUrl = `require${f}.webp')`
                let replaceUrl = `{uri: 'xxxx'}`
                if (data.indexOf(fileName)> 0) {
                  if (requestUrl.indexOf(fileName) > 0) {
                    //  替换的url地址
                    data = data.replace(requestUrl,replaceUrl) 
                    // 写入文件
                    fs.writeFileSync(_src, data)
                  }
                }
              })
            } catch(err) {
              console.log(err)
            }
          } 
        }
      } else if (stats.isDirectory()){
        // 获取目录里面文件
        getFileImageUrl(fileName,_src)
      }
    })
  })
}

同理 一样逻辑 给到一个你想指定去替换的路径 遍历对应这个路径下所以符合你规则的文件,这里我去替换的文件是.tsx || .ts为后缀的文件 然后按客官你自己的业务规则去匹配你需要替换的内容,我这边匹配规则:

上传cdn成功的图片url去匹配文件中相同命名引用的内容以后替换掉

命令行运行你的脚本吧

到这里 是真的就真的完工了

各位看官 欲知后事如何 请听下回分解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值