言·旅·此

示例 进阶

分包大小分析脚本

分析构建产物的包大小,帮助优化分包策略

这是一个用于分析构建产物包大小的脚本示例,帮助优化分包策略。

#!/usr/bin/env node

/**
 * 分包大小分析脚本
 * 分析构建产物的包大小,帮助优化分包策略
 */

import fs from 'node:fs/promises'
import path from 'node:path'
import { fileURLToPath } from 'node:url'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
const projectRoot = path.resolve(__dirname, '..')

async function getFileSize(filePath) {
  try {
    const stats = await fs.stat(filePath)
    return stats.size
  }
  catch {
    return 0
  }
}

function formatSize(bytes) {
  if (bytes === 0)
    return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return `${Number.parseFloat((bytes / (k ** i)).toFixed(2))} ${sizes[i]}`
}

async function analyzeChunks() {
  const distDir = path.join(projectRoot, 'dist', 'client')

  try {
    await fs.access(distDir)
  }
  catch {
    console.error('❌ dist/client directory not found. Please run build first.')
    process.exit(1)
  }

  console.log('📊 Analyzing chunk sizes...\n')

  // 分析 JavaScript 文件
  const jsFiles = []
  const cssFiles = []
  const otherFiles = []

  async function scanDirectory(dir, relativePath = '') {
    const entries = await fs.readdir(dir, { withFileTypes: true })

    for (const entry of entries) {
      const fullPath = path.join(dir, entry.name)
      const relPath = path.join(relativePath, entry.name)

      if (entry.isDirectory()) {
        await scanDirectory(fullPath, relPath)
      }
      else {
        const size = await getFileSize(fullPath)
        const fileInfo = { name: relPath, size, path: fullPath }

        if (entry.name.endsWith('.js')) {
          jsFiles.push(fileInfo)
        }
        else if (entry.name.endsWith('.css')) {
          cssFiles.push(fileInfo)
        }
        else {
          otherFiles.push(fileInfo)
        }
      }
    }
  }

  await scanDirectory(distDir)

  // 排序并显示结果
  jsFiles.sort((a, b) => b.size - a.size)
  cssFiles.sort((a, b) => b.size - a.size)

  console.log('🟨 JavaScript Files:')
  console.log('─'.repeat(80))

  let totalJsSize = 0
  let largeChunks = 0

  for (const file of jsFiles) {
    totalJsSize += file.size
    const sizeStr = formatSize(file.size)
    const isLarge = file.size > 1024 * 1024 // 1MB

    if (isLarge) {
      largeChunks++
      console.log(`🔴 ${file.name.padEnd(50)} ${sizeStr.padStart(10)} (LARGE)`)
    }
    else if (file.size > 500 * 1024) { // 500KB
      console.log(`🟡 ${file.name.padEnd(50)} ${sizeStr.padStart(10)} (MEDIUM)`)
    }
    else {
      console.log(`🟢 ${file.name.padEnd(50)} ${sizeStr.padStart(10)}`)
    }
  }

  console.log('─'.repeat(80))
  console.log(`Total JS: ${formatSize(totalJsSize)}`)
  console.log(`Large chunks (>1MB): ${largeChunks}`)
}

analyzeChunks().catch((error) => {
  console.error('❌ Analysis failed:', error)
  process.exit(1)
})

使用方法

  1. 首先运行构建命令生成 dist 目录
  2. 然后运行此脚本分析包大小
  3. 根据输出的建议优化分包策略