Skip to content

[WIP]feat(pack): surface initial dev compile issues#3155

Open
fireairforce wants to merge 1 commit into
nextfrom
zoomdong/fix-initial-dev-issues-overlay
Open

[WIP]feat(pack): surface initial dev compile issues#3155
fireairforce wants to merge 1 commit into
nextfrom
zoomdong/fix-initial-dev-issues-overlay

Conversation

@fireairforce

Copy link
Copy Markdown
Member

Summary

  • keep the dev server alive when initial entrypoint output contains blocking issues
  • store initial output issues in the existing HMR issue map so clients receive them through sync errors
  • add an optional onCompileDone callback for serve() with structured errors and warnings
  • include warnings in sync/built HMR payloads instead of always sending an empty array
  • cover initial endpoint and project output issue paths with hmr tests

Tests

  • npm -w @utoo/pack run build:js
  • npm -w @utoo/pack test
  • git diff --check

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces an onCompileDone callback option to the dev server and hot reloader, allowing consumers to receive structured compilation errors and warnings after the initial build and subsequent rebuilds. It also updates the HMR sync mechanism to propagate warnings alongside errors, and adds comprehensive tests for these changes. A critical issue was identified in disposeBackgroundWatchSubscriptions where clearing currentEntryIssues entirely would wipe out initial output issues; it is recommended to only clear watcher-related issues to preserve compiled output issues.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +423 to +425
if (clearIssues) {
currentEntryIssues.clear();
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Clearing currentEntryIssues entirely in disposeBackgroundWatchSubscriptions when clearIssues is true will wipe out the initial output issues (keys ending with :output) that were just populated during the entrypoint write phase. This happens because refreshBackgroundWatchers is called after the entrypoints are written to disk, and since backgroundWatchersInitialized is true for subsequent changes, it will clear all issues, causing compile errors/warnings from subsequent entrypoint changes to be lost.

Instead, we should only clear the watcher-related issues (e.g., keys that do not end with :output) to preserve the compiled output issues.

    if (clearIssues) {
      for (const key of currentEntryIssues.keys()) {
        if (!key.endsWith(":output")) {
          currentEntryIssues.delete(key);
        }
      }
    }

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e427078a41

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@@ -0,0 +1,152 @@
import type { Issue } from "@utoo/pack-shared";
import { beforeEach, describe, expect, it, vi } from "vitest";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep tests out of the package build

Because packages/pack/tsconfig.json includes all of src and only excludes src/__test__, this new src/core/hmr.test.ts file is compiled by npm -w @utoo/pack run build:js into both cjs/ and esm/. The published package also exports ./cjs/* and ./esm/*, so this ships a test module that imports vitest even though @utoo/pack does not declare it; moving the test under the existing excluded src/__test__ tree or excluding *.test.ts avoids leaking test-only code into the distributable.

Useful? React with 👍 / 👎.

@github-actions

Copy link
Copy Markdown

📊 Performance Benchmark Report (with-antd)

Utoopack Performance Report

Report ID: utoopack_performance_report_20260612_041615
Generated: 2026-06-12 04:16:15
Trace File: trace_antd.json (0.4GB, 1.11M spans)
Test Project: examples/with-antd


Executive Summary

Metric Value Assessment
Total Wall Time 13,477.3 ms Baseline
Total Thread Work (de-duped) 42,476.7 ms Non-overlapping busy time
Effective Parallelism 3.2x thread_work / wall_time
Working Threads 10 Threads with actual spans
Thread Utilization 31.5% ⚠️ Suboptimal
Total Spans 1,109,255 All B/E + X events
Meaningful Spans (>= 10us) 437,269 (39.4% of total)
Tracing Noise (< 10us) 671,986 (60.6% of total)

Build Phase Timeline

Shows when each build phase is active and how much CPU it consumes.
Self-Time is the time spent exclusively in that phase (excluding children).

Phase Spans Inclusive (ms) Self-Time (ms) Wall Range (ms)
Resolve 110,585 7,644.1 5,966.7 8,846.7
Parse 12,419 2,919.3 2,542.6 12,845.8
Analyze 278,140 31,247.8 23,297.0 12,684.9
Chunk 9,949 3,743.4 1,119.3 11,344.6
Codegen 16,228 2,143.2 2,012.1 11,335.5
Emit 73 49.4 24.5 11,084.6
Other 9,875 7,789.4 4,750.9 13,477.3

Workload Distribution by Diagnostic Tier

Category Spans Inclusive (ms) % Work Self-Time (ms) % Self
P0: Scheduling & Resolution 392,838 39,730.3 93.5% 29,738.0 70.0%
P1: I/O & Heavy Tasks 3,288 236.5 0.6% 211.6 0.5%
P2: Architecture (Locks/Memory) 0 0.0 0.0% 0.0 0.0%
P3: Asset Pipeline 37,264 8,772.7 20.7% 5,640.8 13.3%
P4: Bridge/Interop 0 0.0 0.0% 0.0 0.0%
Other 3,879 6,797.0 16.0% 4,122.6 9.7%

Top 20 Tasks by Self-Time

Self-time is the exclusive duration: time spent in the task itself, not in sub-tasks.
This is the most accurate indicator of where CPU cycles are actually spent.

Self (ms) Inclusive (ms) Count Avg Self (us) P95 Self (ms) Max Self (ms) % Work Task Name Top Caller
14,490.7 19,246.6 180,607 80.2 0.1 52.9 34.1% module write all entrypoints to disk (1%)
4,034.8 4,097.3 27,301 147.8 0.3 195.1 9.5% analyze ecmascript module module (64%)
3,583.6 3,908.4 62,462 57.4 0.1 21.7 8.4% internal resolving resolving (30%)
3,383.3 6,474.4 59,083 57.3 0.1 18.8 8.0% process module module (18%)
2,346.7 3,699.3 47,426 49.5 0.0 29.8 5.5% resolving module (36%)
2,236.0 2,261.3 27 82815.1 343.1 527.0 5.3% save snapshot persist (4%)
2,108.0 2,249.4 9,078 232.2 0.7 96.2 5.0% parse ecmascript process module (28%)
1,187.1 1,187.1 7,900 150.3 0.5 235.3 2.8% compute async module info compute merged modules (0%)
1,154.8 1,154.8 12,164 94.9 0.4 12.0 2.7% precompute code generation generate merged code (38%)
950.3 3,572.9 7,678 123.8 0.2 65.3 2.2% chunking compute async chunks (0%)
873.1 2,555.6 2,037 428.6 0.8 334.4 2.1% generate merged code chunking (43%)
594.2 947.8 5,268 112.8 0.0 321.1 1.4% write all entrypoints to disk None (0%)
554.0 571.4 1,420 390.1 1.8 29.5 1.3% webpack loader parse css (10%)
483.2 483.2 486 994.3 0.6 286.0 1.1% generate source map code generation (91%)
394.4 801.5 160 2465.1 4.5 241.7 0.9% emit code generate merged code (25%)
374.1 505.2 3,578 104.6 0.3 62.6 0.9% code generation chunking (12%)
283.9 519.2 823 344.9 1.3 31.2 0.7% parse css module (6%)
164.3 165.8 2,177 75.4 0.1 13.5 0.4% compute async chunks compute async chunks (0%)
150.6 150.6 2,508 60.0 0.1 13.1 0.4% read file parse ecmascript (85%)
117.5 117.5 1,186 99.1 0.0 28.9 0.3% compute binding usage info write all entrypoints to disk (0%)

Critical Path Analysis

The longest sequential dependency chains that determine wall-clock time.
Focus on reducing the depth of these chains to improve parallelism.

Rank Self-Time (ms) Depth Path
1 576.1 3 chunking → generate merged code → emit code
2 531.8 3 persist → save snapshot → blocking
3 358.1 4 chunking → generate merged code → emit code → generate source map
4 343.3 2 save snapshot → blocking
5 195.2 2 process module → analyze ecmascript module

Batching Candidates

High-volume tasks dominated by a single parent. If the parent can batch them,
it drastically reduces scheduler overhead.

Task Name Count Top Caller (Attribution) Avg Self P95 Self Total Self
No obvious batching candidates found - - - - -

Duration Distribution

Range Count Percentage
<10us 671,986 60.6%
10us-100us 408,498 36.8%
100us-1ms 20,909 1.9%
1ms-10ms 7,335 0.7%
10ms-100ms 504 0.0%
>100ms 23 0.0%

Action Items

  1. [P0] Focus on tasks with the highest Self-Time — these are where CPU cycles are actually spent.
  2. [P0] Use Batching Candidates to identify callers that should use try_join or reduce #[turbo_tasks::function] granularity.
  3. [P1] Check Build Phase Timeline for phases with disproportionate wall range vs. self-time (= serialization).
  4. [P1] Inspect P95 Self (ms) for heavy monolith tasks. Focus on long-tail outliers, not averages.
  5. [P1] Review Critical Paths — reducing the longest chain depth directly improves wall-clock time.
  6. [P2] If Thread Utilization < 60%, investigate scheduling gaps (lock contention or deep dependency chains).

Report generated by Utoopack Performance Analysis Agent

@fireairforce fireairforce changed the title feat(pack): surface initial dev compile issues [WIP]feat(pack): surface initial dev compile issues Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant