webpack 自定义插件配置图片上传oss、ftp、cdn

在开发小程序的时候因为包的大小受限,致使不少公司购买oss,cdn,单独弄台服务器上传静态资源,

可是前端本身一张一张上传实在显得太笨拙,仍是开发自动化的脚原本的舒服,最重要的缘由是维护

旧代码,致使本身无法彻底找到全部的图片相关代码实在坑爹,因此想办法一次性解决。

这里的方法适用小程序第三方框架,mpvue,taro,uni-app等webpack构建的框架

web固然也是支持的

思路

一开始想到的办法就是项目打包完毕后将图片文件夹内的图片所有上传,配置url-loader将图片路径
所有替换成网络路径,途中遇到不少坑,待我一一道来。前端

步骤

1.首先到webpack官网找到打包完毕的钩子,让后在钩子里作点事

  • 相关钩子文档 webpack钩子
  • 我这里使用的是(afterEmit):生成资源到 output 目录以后。 — 直接上代码
class OssPlugin {
  apply(compiler) {
    compiler.hooks.afterEmit.tapAsync('done', (compilation, callback) => {
      // 此处经过node api读取打包文件列表
      fs.readdir('build/images', (err, files) => {
        if (err) {
          console.error(err)
        } else {
          uploadImg(files)
        }
      })
      // 记得调用callback避免webpack后续动做不执行
      callback()
    })
  
复制代码

2.编写图片上传函数,此处demo为阿里云oss

async function uploadImg(files) {
  let OSS = require('ali-oss')

  let client = new OSS({
    region: 'oss-cn-shenzhen', // cdn节点位置
    accessKeyId: '',
    accessKeySecret: '',
    bucket: '', // oss bucket目录
  });

  // 此处为循环上传,用for循环相信各位大佬都了解(避免并行上传出错)
  // 同时方便统计是否上传完毕
  for (let i = 0, len = files.length; i < len; i++) {
    // common/${files[i]}为上传后路径,阿里云支持指定上传后文件名
    // 指定文件名是必须的,由于生成的网络路径是拼接好的,不知道其余平台支不支持,这一步尤其关键,不支持就作不了下一步
    await client.put(`common/${files[i]}`, `build/images/${files[i]}`);
  }

  // 图片上传完毕后删除图片
  for (let i = 0, len = files.length; i < len; i++) {
    fs.unlinkSync(`dist/common/${files[i]}`)
  }

  console.log('\x1B[44m%s\x1B[49m', 'upload img fished>>>>>>>>>>>>>>>')
}
复制代码

是否是很简单的就完成了一个webpack插件,是否是也能成为webpack大佬了vue

2.最重要的步骤来了,配置图片路径

{
  test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
  loader: require.resolve('url-loader'),
  options: {
    // 正式环境一概不使用base64,所有打包为文件
    limit: isEnvProduction ? imageInlineSizeLimit : 0,
    // 此处两个配置尤其重要,路径会拼接为:http://movie.xmwhs88.com/images/[name].[hash:8].[ext]
    // images必定要和上传后生成的路径一至
    name: 'images/[name].[hash:8].[ext]',
    // publicPath记得加上http:(https:)避免转换成绝对路径
    publicPath: isEnvDevelopment ? '' : 'http://movie.xmwhs88.com/'
  },
},
复制代码

若是你也有须要和我同样部分图片不须要上传,请写两个url-loader配置,test正则单独匹配,不上传的文件目录单独制定(就是前面的images换一个,避免被删)
文件名统一规范node

3,最后别忘了在webpack,plugin里面加上你的插件

后记

是否是超级简单,若是你有ftp上传的需求,参考如下代码react

// 此处使用sftp,ftp请自行谷歌
const Sftp = require('node-ssh');

const ftpConfig = {
  host: '',
  port: '22',
  username: '',
  password: ''
}

function uploadImg() {
  return new Promise((resolve, reject) => {
    let ssh = new Sftp()
    ssh.connect(ftpConfig).then(() => {
      // 支持上传文件夹
      ssh.putDirectory(/* 本地 */'build/images', /* 远程 */'public/images').then(() => {
        resolve()
        // 上传完毕以后记得关闭,避免进程一直存在须要手动关闭
        ssh.dispose()
      }).catch(err => {
        reject(err)
        ssh.dispose()
      })
    }).catch(err => {
      reject(err)
      ssh.dispose()
    })
  })
}
复制代码

配置关键点在于上传时机和图片路径 以为能够请给我666 基于create-react-app脚手架改造的项目地址:webpack-cdn-imgwebpack

相关文章
相关标签/搜索