{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type { Plugin } from 'vite'\n\nexport interface ImagePreloaderOptions {\n  /** 图片文件扩展名 */\n  extensions?: string[]\n  \n  /** 是否在控制台显示预加载信息 */\n  verbose?: boolean\n  \n  /** 框架类型 */\n  framework?: 'react' | 'vue' | 'auto'\n  \n  /** 是否只在开发模式下启用 */\n  devOnly?: boolean\n  \n  /** 预加载延迟时间 (ms) */\n  delay?: number\n}\n\ninterface ImageInfo {\n  source: string\n  url: string\n  type: 'import' | 'require' | 'url'\n}\n\nfunction imagePreloader(options: ImagePreloaderOptions = {}): Plugin {\n  const {\n    extensions = ['png', 'jpg', 'jpeg', 'gif', 'svg', 'webp', 'avif'],\n    verbose = true,\n    framework = 'auto',\n    devOnly = true,\n    delay = 1000\n  } = options\n\n  let isDevMode = false\n  let detectedFramework: 'react' | 'vue' | 'vanilla' = 'vanilla'\n  const discoveredImages = new Set<string>()\n\n  // 创建匹配图片的正则表达式\n  const imageExtPattern = extensions.join('|')\n  const patterns = {\n    // import xxx from './image.png'\n    // import { xxx } from './image.png'\n    importStatement: new RegExp(`import\\\\s+(?:[^'\"]+\\\\s+from\\\\s+)?['\"]([^'\"]+\\\\.(${imageExtPattern}))['\"]`, 'gi'),\n    \n    // require('./image.png')\n    requireStatement: new RegExp(`require\\\\(['\"]([^'\"]+\\\\.(${imageExtPattern}))['\"]\\\\)`, 'gi'),\n    \n    // url('./image.png') 或 url(\"./image.png\")\n    urlStatement: new RegExp(`url\\\\(['\"]([^'\"]+\\\\.(${imageExtPattern}))['\"]\\\\)`, 'gi'),\n    \n    // src=\"./image.png\" 或 src='./image.png'\n    srcAttribute: new RegExp(`src=['\"]([^'\"]+\\\\.(${imageExtPattern}))['\"]`, 'gi'),\n    \n    // background-image: url('./image.png')\n    cssUrl: new RegExp(`background-image\\\\s*:\\\\s*url\\\\(['\"]([^'\"]+\\\\.(${imageExtPattern}))['\"]\\\\)`, 'gi'),\n    \n    // HTTP/HTTPS 图片URL (支持查询参数)\n    // 匹配 https://domain.com/path/to/image 或带查询参数的URL\n    httpImageUrl: new RegExp(`['\"](https?://[^'\"\\\\s]+(?:\\\\?[^'\"\\\\s]*)?(?:&[^'\"\\\\s]*)*)['\"]`, 'gi'),\n    \n    // 匹配包含 image 关键词的API URL\n    apiImageUrl: new RegExp(`['\"]([^'\"]*(?:image|img|photo|pic)[^'\"]*(?:\\\\?[^'\"]*)?(?:&[^'\"]*)*)['\"]`, 'gi')\n  }\n\n  const extractImagesFromCode = (code: string, id: string): ImageInfo[] => {\n    const images: ImageInfo[] = []\n    \n    // 匹配 import 语句\n    let match: RegExpExecArray | null\n    while ((match = patterns.importStatement.exec(code)) !== null) {\n      images.push({\n        source: match[0],\n        url: match[1],\n        type: 'import'\n      })\n    }\n    \n    // 匹配 require 语句\n    patterns.requireStatement.lastIndex = 0\n    while ((match = patterns.requireStatement.exec(code)) !== null) {\n      images.push({\n        source: match[0],\n        url: match[1],\n        type: 'require'\n      })\n    }\n    \n    // 匹配 url() 语句\n    patterns.urlStatement.lastIndex = 0\n    while ((match = patterns.urlStatement.exec(code)) !== null) {\n      images.push({\n        source: match[0],\n        url: match[1],\n        type: 'url'\n      })\n    }\n    \n    // 匹配 src 属性\n    patterns.srcAttribute.lastIndex = 0\n    while ((match = patterns.srcAttribute.exec(code)) !== null) {\n      images.push({\n        source: match[0],\n        url: match[1],\n        type: 'url'\n      })\n    }\n    \n    // 匹配 CSS background-image\n    patterns.cssUrl.lastIndex = 0\n    while ((match = patterns.cssUrl.exec(code)) !== null) {\n      images.push({\n        source: match[0],\n        url: match[1],\n        type: 'url'\n      })\n    }\n    \n    // 匹配 HTTP/HTTPS 图片URL\n    patterns.httpImageUrl.lastIndex = 0\n    while ((match = patterns.httpImageUrl.exec(code)) !== null) {\n      const url = match[1]\n      // 检查是否是图片相关的URL\n      if (url.includes('image') || url.includes('img') || url.includes('photo') || url.includes('pic') || \n          url.includes('avatar') || url.includes('thumb') || url.includes('banner') ||\n          // 检查是否包含图片文件扩展名\n          new RegExp(`\\\\.(${imageExtPattern})(?:\\\\?|$)`, 'i').test(url)) {\n        images.push({\n          source: match[0],\n          url: url,\n          type: 'url'\n        })\n      }\n    }\n    \n    // 匹配包含 image 关键词的API URL\n    patterns.apiImageUrl.lastIndex = 0\n    while ((match = patterns.apiImageUrl.exec(code)) !== null) {\n      const url = match[1]\n      // 确保是完整的URL\n      if (url.startsWith('http://') || url.startsWith('https://')) {\n        images.push({\n          source: match[0],\n          url: url,\n          type: 'url'\n        })\n      }\n    }\n    \n    return images\n  }\n\n  const generatePreloaderScript = (): string => {\n    const imageUrls = JSON.stringify(Array.from(discoveredImages))\n    \n    return `\n<script>\n  (function() {\n    const imageUrls = ${imageUrls};\n    const preloadedImages = new Set();\n    const batchSize = 5; // 每批处理5张图片\n    const batchInterval = 3000; // 每批间隔3秒\n    \n    // 预加载图片并处理 301 重定向\n    function preloadImage(url, retryCount = 0) {\n      return new Promise((resolve) => {\n        const img = new Image();\n        \n        img.onload = () => {\n          // 检查是否被重定向到默认图片\n          // 301重定向后，img.src会是重定向后的URL\n          const isDefaultImage = img.src.includes('page_image/default.jpeg');\n          \n          if (${verbose}) {\n            if (isDefaultImage) {\n              console.log(\\`🔄 [Image Preloader] 检测到默认图片，开始后台轮询: \\${url}\\`);\n              console.log(\\`   重定向到: \\${img.src}\\`);\n            } else {\n              console.log(\\`✅ [Image Preloader] 成功加载真实图片: \\${url}\\`);\n            }\n          }\n          \n          // 无论是否为默认图片，都标记为已加载\n          preloadedImages.add(url);\n          \n          // 如果是默认图片，启动后台轮询任务\n          if (isDefaultImage && retryCount < 30) {\n            // 先让默认图片显示，然后开始轮询\n            resolve();\n            startBackgroundPolling(url, img.src, retryCount);\n          } else {\n            resolve();\n          }\n        };\n        \n        img.onerror = () => {\n          if (${verbose}) {\n            console.warn(\\`❌ [Image Preloader] 图片加载失败: \\${url}\\`);\n          }\n          resolve();\n        };\n        \n        // 添加时间戳避免缓存\n        const timestamp = Date.now();\n        const separator = url.includes('?') ? '&' : '?';\n        img.src = \\`\\${url}\\${separator}_t=\\${timestamp}\\`;\n      });\n    }\n    \n         // 后台轮询函数\n     function startBackgroundPolling(originalUrl, defaultImageUrl, retryCount = 0) {\n      if (retryCount >= 30) {\n        if (${verbose}) {\n          console.log(\\`⏰ [Image Preloader] 达到最大重试次数，停止轮询: \\${originalUrl}\\`);\n        }\n        return;\n      }\n      \n      setTimeout(() => {\n        if (${verbose}) {\n          console.log(\\`🔄 [Image Preloader] 后台轮询中... (\\${retryCount + 1}/30): \\${originalUrl}\\`);\n        }\n        \n        const img = new Image();\n        img.onload = () => {\n          const isStillDefaultImage = img.src.includes('page_image/default.jpeg');\n          \n          if (!isStillDefaultImage) {\n            // 获取到真实图片了，更新页面中所有使用该URL的图片\n            updatePageImages(originalUrl, img.src);\n            if (${verbose}) {\n              console.log(\\`🎉 [Image Preloader] 后台轮询成功，已更新页面图片: \\${originalUrl}\\`);\n              console.log(\\`   新图片URL: \\${img.src}\\`);\n            }\n          } else {\n            // 还是默认图片，继续轮询\n            startBackgroundPolling(originalUrl, defaultImageUrl, retryCount + 1);\n          }\n        };\n        \n        img.onerror = () => {\n          // 请求失败，继续轮询\n          startBackgroundPolling(originalUrl, defaultImageUrl, retryCount + 1);\n        };\n        \n        // 添加时间戳避免缓存\n        const timestamp = Date.now();\n        const separator = originalUrl.includes('?') ? '&' : '?';\n        img.src = \\`\\${originalUrl}\\${separator}_t=\\${timestamp}\\`;\n      }, 10000); // 10秒后重试\n    }\n    \n         // 更新页面中所有使用指定URL的图片元素\n     function updatePageImages(originalUrl, newImageUrl) {\n      if (${verbose}) {\n        console.log(\\`🔄 [Image Preloader] 开始更新页面图片: \\${originalUrl} -> \\${newImageUrl}\\`);\n      }\n      \n      let updateCount = 0;\n      \n      // 更新所有img标签\n      const images = document.querySelectorAll('img');\n      images.forEach(img => {\n        // 检查多种可能的匹配方式\n        const imgSrc = img.src;\n        const imgSrcWithoutTimestamp = imgSrc.split('_t=')[0].split('?_t=')[0];\n        const originalUrlWithoutTimestamp = originalUrl.split('_t=')[0].split('?_t=')[0];\n        \n        // 检查是否匹配（包括301重定向后的URL）\n        const isMatch = \n          imgSrcWithoutTimestamp === originalUrlWithoutTimestamp ||\n          img.getAttribute('data-original-src') === originalUrl ||\n          img.getAttribute('src') === originalUrl ||\n          // 检查是否是默认图片需要更新\n          (imgSrc.includes('page_image/default.jpeg') && img.hasAttribute('data-api-url') && img.getAttribute('data-api-url') === originalUrl);\n        \n        if (isMatch) {\n          if (${verbose}) {\n            console.log(\\`🔄 [Image Preloader] 更新页面图片元素: \\${imgSrc} -> \\${newImageUrl}\\`);\n          }\n          // 保存原始URL到data属性，用于下次匹配\n          img.setAttribute('data-original-src', originalUrl);\n          img.setAttribute('data-api-url', originalUrl);\n          img.src = newImageUrl;\n          updateCount++;\n        }\n      });\n      \n            // 更新所有背景图片\n      const allElements = document.querySelectorAll('*');\n      allElements.forEach(el => {\n        const computedStyle = window.getComputedStyle(el);\n        const backgroundImage = computedStyle.backgroundImage;\n        \n        if (backgroundImage && backgroundImage !== 'none') {\n          // 提取URL\n          const urlMatch = backgroundImage.match(/url\\\\(['\"]?([^'\"\\\\)]+)['\"]?\\\\)/);\n          if (urlMatch) {\n            const bgUrl = urlMatch[1];\n            const bgUrlWithoutTimestamp = bgUrl.split('_t=')[0].split('?_t=')[0];\n            const originalUrlWithoutTimestamp = originalUrl.split('_t=')[0].split('?_t=')[0];\n            \n            const isBgMatch = \n              bgUrlWithoutTimestamp === originalUrlWithoutTimestamp ||\n              (bgUrl.includes('page_image/default.jpeg') && el.hasAttribute('data-api-bg-url') && el.getAttribute('data-api-bg-url') === originalUrl);\n            \n            if (isBgMatch) {\n               if (${verbose}) {\n                 console.log(\\`🔄 [Image Preloader] 更新背景图片: \\${bgUrl} -> \\${newImageUrl}\\`);\n               }\n               el.setAttribute('data-api-bg-url', originalUrl);\n               el.style.backgroundImage = \\`url('\\${newImageUrl}')\\`;\n               updateCount++;\n            }\n          }\n        }\n      });\n      \n      if (${verbose}) {\n        console.log(\\`✅ [Image Preloader] 图片更新完成，共更新了 \\${updateCount} 个元素\\`);\n      }\n    }\n    \n    // 分批预加载图片\n    function preloadImagesBatch() {\n      // 将图片URL分成批次\n      const batches = [];\n      for (let i = 0; i < imageUrls.length; i += batchSize) {\n        batches.push(imageUrls.slice(i, i + batchSize));\n      }\n      \n      if (${verbose}) {\n        console.log('%c🖼️ Image Preloader:', 'color: #10b981; font-weight: bold;', \n          \\`Starting batch preload: \\${imageUrls.length} images in \\${batches.length} batches\\`);\n      }\n      \n      // 逐批处理\n      batches.forEach((batch, batchIndex) => {\n        setTimeout(() => {\n          if (${verbose}) {\n            console.log('%c🖼️ Image Preloader:', 'color: #10b981; font-weight: bold;', \n              \\`Processing batch \\${batchIndex + 1}/\\${batches.length} (\\${batch.length} images)\\`);\n          }\n          \n          const promises = batch.map(url => preloadImage(url).catch(e => null));\n          \n          Promise.allSettled(promises).then(results => {\n            const loaded = results.filter(r => r.status === 'fulfilled').length;\n            const failed = results.filter(r => r.status === 'rejected').length;\n            \n            if (${verbose}) {\n              console.log('%c🖼️ Image Preloader:', 'color: #10b981; font-weight: bold;', \n                \\`Batch \\${batchIndex + 1} completed: \\${loaded} loaded\\` + (failed > 0 ? \\`, \\${failed} failed\\` : ''));\n              \n              // 如果是最后一批，显示总结\n              if (batchIndex === batches.length - 1) {\n                const totalLoaded = preloadedImages.size;\n                const totalFailed = imageUrls.length - totalLoaded;\n                console.log('%c🖼️ Image Preloader:', 'color: #10b981; font-weight: bold;', \n                  \\`All batches completed: \\${totalLoaded} total loaded\\` + (totalFailed > 0 ? \\`, \\${totalFailed} failed\\` : ''));\n              }\n            }\n          });\n        }, batchIndex * batchInterval);\n      });\n    }\n    \n    // 兼容旧的API\n    function preloadAllImages() {\n      preloadImagesBatch();\n    }\n    \n    // 监控页面上的图片，自动处理默认图片\n    function monitorPageImages() {\n      const observer = new MutationObserver((mutations) => {\n        mutations.forEach((mutation) => {\n          mutation.addedNodes.forEach((node) => {\n            if (node.nodeType === Node.ELEMENT_NODE) {\n              const element = node;\n              \n              // 检查新添加的img元素\n              if (element.tagName === 'IMG') {\n                checkAndMarkApiImage(element);\n              }\n              \n              // 检查子元素中的img\n              const imgs = element.querySelectorAll ? element.querySelectorAll('img') : [];\n              imgs.forEach(checkAndMarkApiImage);\n            }\n          });\n        });\n      });\n      \n      // 开始观察\n      observer.observe(document.body, {\n        childList: true,\n        subtree: true\n      });\n      \n      // 检查已存在的图片\n      document.querySelectorAll('img').forEach(checkAndMarkApiImage);\n    }\n    \n    function checkAndMarkApiImage(img) {\n      const src = img.src;\n      if (!src) return;\n      \n      // 检查是否是我们关心的API URL\n      const isApiUrl = imageUrls.some(url => {\n        const cleanUrl = url.split('_t=')[0].split('?_t=')[0];\n        const cleanSrc = src.split('_t=')[0].split('?_t=')[0];\n        return cleanUrl === cleanSrc;\n      });\n      \n      if (isApiUrl) {\n        // 找到对应的原始URL\n        const originalUrl = imageUrls.find(url => {\n          const cleanUrl = url.split('_t=')[0].split('?_t=')[0];\n          const cleanSrc = src.split('_t=')[0].split('?_t=')[0];\n          return cleanUrl === cleanSrc;\n        });\n        \n        if (originalUrl) {\n          img.setAttribute('data-api-url', originalUrl);\n          \n          if (${verbose}) {\n            console.log(\\`🏷️ [Image Preloader] 标记API图片: \\${src} (原始: \\${originalUrl})\\`);\n          }\n          \n          // 如果检测到默认图片，启动轮询\n          if (src.includes('page_image/default.jpeg')) {\n            if (${verbose}) {\n              console.log(\\`🔄 [Image Preloader] 页面检测到默认图片，启动后台轮询: \\${originalUrl}\\`);\n            }\n            startBackgroundPolling(originalUrl, src, 0);\n          }\n        }\n      }\n    }\n    \n    // 延迟预加载，避免阻塞初始页面渲染\n    setTimeout(preloadImagesBatch, ${delay});\n    \n    // 启动页面图片监控\n    setTimeout(monitorPageImages, 100);\n    \n    // 导出到全局，方便调试\n    window.__imagePreloader = {\n      preloadAllImages,\n      preloadImagesBatch,\n      startImagePolling: startBackgroundPolling, // 更新为后台轮询\n      getPreloadedImages: () => Array.from(preloadedImages),\n      imageUrls,\n      batchSize,\n      batchInterval,\n      pollInterval: 10000,\n      maxAttempts: 30,\n      updatePageImages // 新增：手动更新图片的方法\n    };\n  })();\n</script>`\n  }\n\n  return {\n    name: 'vite-plugin-image-preloader',\n    \n    configResolved(config) {\n      isDevMode = config.command === 'serve'\n      \n      // 自动检测框架\n      if (framework === 'auto') {\n        try {\n          const packageJsonPath = config.root + '/package.json'\n          const fs = require('fs')\n          if (fs.existsSync(packageJsonPath)) {\n            const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))\n            const allDeps = {\n              ...packageJson.dependencies,\n              ...packageJson.devDependencies\n            }\n            \n            if (allDeps.react) {\n              detectedFramework = 'react'\n            } else if (allDeps.vue) {\n              detectedFramework = 'vue'\n            }\n          }\n        } catch {\n          // 忽略错误，使用默认值\n        }\n      } else {\n        detectedFramework = framework\n      }\n      \n      if (verbose && isDevMode) {\n        console.log('🖼️  Image Preloader Plugin enabled for', detectedFramework)\n      }\n    },\n\n    transform(code, id) {\n      if (devOnly && !isDevMode) return null\n      \n      // 只处理相关文件类型\n      const shouldProcess = \n        id.endsWith('.tsx') || \n        id.endsWith('.ts') || \n        id.endsWith('.jsx') || \n        id.endsWith('.js') || \n        id.endsWith('.vue') || \n        id.endsWith('.css') || \n        id.endsWith('.scss') || \n        id.endsWith('.sass') || \n        id.endsWith('.less')\n      \n      if (!shouldProcess) return null\n      \n      const images = extractImagesFromCode(code, id)\n      \n      if (images.length > 0) {\n        images.forEach(img => {\n          // 处理相对路径，转换为绝对路径\n          let resolvedUrl = img.url\n          if (img.url.startsWith('./') || img.url.startsWith('../')) {\n            // 对于相对路径，保持原样，让 Vite 处理\n            resolvedUrl = img.url\n          } else if (!img.url.startsWith('/') && !img.url.startsWith('http')) {\n            // 对于不以 / 或 http 开头的路径，添加 /\n            resolvedUrl = '/' + img.url\n          }\n          \n          discoveredImages.add(resolvedUrl)\n        })\n        \n                 if (verbose) {\n           console.log(`🖼️  Found ${images.length} image(s) in ${id.split('/').pop()}`)\n           images.forEach(img => {\n             console.log(`   ${img.type}: ${img.url}`)\n           })\n         }\n      }\n      \n      return null // 不修改代码\n    },\n\n    transformIndexHtml: {\n      order: 'post',\n      handler(html) {\n        if (devOnly && !isDevMode) return html\n        if (discoveredImages.size === 0) return html\n\n        const preloaderScript = generatePreloaderScript()\n        \n        // 在 head 标签结束前注入预加载脚本\n        const headIndex = html.indexOf('</head>')\n        if (headIndex !== -1) {\n          return html.slice(0, headIndex) + preloaderScript + html.slice(headIndex)\n        }\n        \n        return html\n      }\n    }\n  }\n}\n\n// 同时支持命名导出和默认导出\nexport { imagePreloader }\nexport default imagePreloader "],"mappings":"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","names":[]}