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

相關文章
相關標籤/搜索