$preserve 삭제하지 않을 최상위 항목명 * @return array 삭제한 최상위 항목명 목록 */ private function pruneBuildOutput(string $buildPath, array $preserve = ['vendor']): array { $distPath = rtrim($buildPath, '/\\').DIRECTORY_SEPARATOR.'dist'; if (! File::isDirectory($distPath)) { return []; } $removed = []; foreach (new \FilesystemIterator($distPath, \FilesystemIterator::SKIP_DOTS) as $item) { $name = $item->getBasename(); if (in_array($name, $preserve, true)) { continue; } $deleted = $item->isDir() ? File::deleteDirectory($item->getPathname()) : File::delete($item->getPathname()); if ($deleted) { $removed[] = $name; continue; } // 삭제 실패는 빌드를 막을 이유가 못 된다 — vite 가 같은 경로를 덮어쓴다. // 다만 조용히 넘기면 stale 산출물이 남은 것을 알 수 없으므로 기록한다. Log::warning('빌드 산출물 정리 실패 (다음 빌드에서 재시도)', [ 'path' => $item->getPathname(), ]); } return $removed; } }