( environment: Environment, depsInfo: Record<string, OptimizedDepInfo>, )
| 518 | * the metadata and start the server without waiting for the optimizeDeps processing to be completed |
| 519 | */ |
| 520 | export function runOptimizeDeps( |
| 521 | environment: Environment, |
| 522 | depsInfo: Record<string, OptimizedDepInfo>, |
| 523 | ): { |
| 524 | cancel: () => Promise<void> |
| 525 | result: Promise<DepOptimizationResult> |
| 526 | } { |
| 527 | const optimizerContext = { cancelled: false } |
| 528 | |
| 529 | const depsCacheDir = getDepsCacheDir(environment) |
| 530 | const processingCacheDir = getProcessingDepsCacheDir(environment) |
| 531 | |
| 532 | // Create a temporary directory so we don't need to delete optimized deps |
| 533 | // until they have been processed. This also avoids leaving the deps cache |
| 534 | // directory in a corrupted state if there is an error |
| 535 | fs.mkdirSync(processingCacheDir, { recursive: true }) |
| 536 | |
| 537 | // a hint for Node.js |
| 538 | // all files in the cache directory should be recognized as ES modules |
| 539 | debug?.(colors.green(`creating package.json in ${processingCacheDir}`)) |
| 540 | fs.writeFileSync( |
| 541 | path.resolve(processingCacheDir, 'package.json'), |
| 542 | `{\n "type": "module"\n}\n`, |
| 543 | ) |
| 544 | |
| 545 | const metadata = initDepsOptimizerMetadata(environment) |
| 546 | |
| 547 | metadata.browserHash = getOptimizedBrowserHash( |
| 548 | metadata.hash, |
| 549 | depsFromOptimizedDepInfo(depsInfo), |
| 550 | ) |
| 551 | |
| 552 | // We prebundle dependencies with esbuild and cache them, but there is no need |
| 553 | // to wait here. Code that needs to access the cached deps needs to await |
| 554 | // the optimizedDepInfo.processing promise for each dep |
| 555 | |
| 556 | const qualifiedIds = Object.keys(depsInfo) |
| 557 | let cleaned = false |
| 558 | let committed = false |
| 559 | const cleanUp = () => { |
| 560 | // If commit was already called, ignore the clean up even if a cancel was requested |
| 561 | // This minimizes the chances of leaving the deps cache in a corrupted state |
| 562 | if (!cleaned && !committed) { |
| 563 | cleaned = true |
| 564 | // No need to wait, we can clean up in the background because temp folders |
| 565 | // are unique per run |
| 566 | debug?.(colors.green(`removing cache dir ${processingCacheDir}`)) |
| 567 | try { |
| 568 | // When exiting the process, `fsp.rm` may not take effect, so we use `fs.rmSync` |
| 569 | fs.rmSync(processingCacheDir, { recursive: true, force: true }) |
| 570 | } catch { |
| 571 | // Ignore errors |
| 572 | } |
| 573 | } |
| 574 | } |
| 575 | |
| 576 | const successfulResult: DepOptimizationResult = { |
| 577 | metadata, |
no test coverage detected