Skip to content

feat(egg): skip loadRouter in metadataOnly mode#5847

Merged
killagu merged 1 commit intonextfrom
feat/tegg-metadata-only
Mar 30, 2026
Merged

feat(egg): skip loadRouter in metadataOnly mode#5847
killagu merged 1 commit intonextfrom
feat/tegg-metadata-only

Conversation

@killagu
Copy link
Copy Markdown
Contributor

@killagu killagu commented Mar 30, 2026

Summary

  • AppWorkerLoader.load()metadataOnly 模式下跳过 loadRouter(),避免不必要的路由注册
  • egg-bin manifest generate 命令的 metadata-only 启动服务
  • 新增 6 个测试用例覆盖 metadataOnly 和正常模式对比

Context

PR #5842 manifest 系列的第三部分。lifecycle 层的 loadMetadata / triggerLoadMetadata / metadataOnly flag 已在 #5844#5846 中合入,本 PR 补全 AppWorkerLoader 侧的守卫。

Test plan

  • metadataOnly 模式:仅调用 loadMetadata,跳过正常生命周期钩子
  • metadataOnly 模式:router.stack 为空(loadRouter 被跳过)
  • metadataOnly 模式:不创建 agent
  • 正常模式:生命周期钩子正常触发,路由正常注册
  • pnpm --filter=egg run test test/start.test.ts 6/6 通过

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added metadata-only initialization mode that conditionally skips router registration during app startup, enabling metadata extraction without full application initialization.
  • Tests

    • Added test coverage for metadata-only startup mode, verifying correct lifecycle behavior and router initialization is prevented.
    • Added test suite for standard initialization mode to validate baseline functionality remains unchanged.

AppWorkerLoader.load() now gates loadRouter() behind !metadataOnly,
allowing manifest-only startup to skip route registration entirely.
This serves the egg-bin manifest generate command.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 30, 2026 09:41
@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying egg with  Cloudflare Pages  Cloudflare Pages

Latest commit: 07e9277
Status: ✅  Deploy successful!
Preview URL: https://6c410714.egg-cci.pages.dev
Branch Preview URL: https://feat-tegg-metadata-only.egg-cci.pages.dev

View logs

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

The changes introduce a "metadata-only" mode to the application loader that conditionally skips router initialization based on a flag. A new test fixture app and expanded test suite verify that metadata-only mode prevents router registration and agent creation while maintaining proper lifecycle hook execution.

Changes

Cohort / File(s) Summary
Loader Control Flow
packages/egg/src/lib/loader/AppWorkerLoader.ts
Modified load() to conditionally skip loadRouter() when metadataOnly option is true, altering initialization flow.
Metadata-Only Test Fixture App
packages/egg/test/fixtures/apps/metadata-only-app/package.json, metadata-only-app/app.js, metadata-only-app/app/controller/home.js, metadata-only-app/app/router.js
New test fixture application structure with boot lifecycle logger class, simple home controller returning 'hello', and basic router configuration.
Start Mode Tests
packages/egg/test/start.test.ts
Replaced inactive test suite with active tests covering metadataOnly mode (skips router, no agent) and normal mode (standard lifecycle, routes registered), with explicit beforeAll/afterAll lifecycle management.

Sequence Diagram

sequenceDiagram
    participant Loader as AppWorkerLoader
    participant Boot as Boot Hooks
    participant Router as Router
    participant Agent as Agent

    rect rgba(100, 200, 100, 0.5)
    Note over Loader,Agent: Metadata-Only Mode (metadataOnly: true)
    Loader->>Boot: configWillLoad()
    Boot-->>Loader: done
    Loader->>Boot: configDidLoad()
    Boot-->>Loader: done
    Loader->>Boot: loadMetadata()
    Boot-->>Loader: done
    Note over Router,Agent: Router & Agent initialization skipped
    end

    rect rgba(100, 150, 200, 0.5)
    Note over Loader,Agent: Normal Mode (metadataOnly: false)
    Loader->>Boot: configWillLoad()
    Boot-->>Loader: done
    Loader->>Boot: configDidLoad()
    Boot-->>Loader: done
    Loader->>Boot: didLoad()
    Boot-->>Loader: done
    Loader->>Router: loadRouter()
    Router-->>Loader: routes registered
    Loader->>Agent: create agent
    Agent-->>Loader: agent ready
    Loader->>Boot: willReady()
    Boot-->>Loader: done
    end
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A flag to skip the routing dance,
Just metadata in metadata's trance,
Boot hooks log their steady way,
While agents rest another day!
The fixture app, a test's delight,
New modes boot up just right. ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically summarizes the main change: skipping loadRouter when metadataOnly mode is enabled in the egg framework.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/tegg-metadata-only

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying egg-v3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 07e9277
Status: ✅  Deploy successful!
Preview URL: https://f3e69eb3.egg-v3.pages.dev
Branch Preview URL: https://feat-tegg-metadata-only.egg-v3.pages.dev

View logs

Copy link
Copy Markdown
Contributor

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

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 a metadataOnly mode to the AppWorkerLoader, which prevents the router from being loaded when enabled. The changes include a new test fixture and a comprehensive test suite in start.test.ts to verify that lifecycle hooks and route registrations behave correctly in both metadata-only and normal operation modes. A review comment suggests increasing the precision of a test assertion regarding the number of registered routes.

});

it('should register routes', () => {
assert(app.router.stack.length > 0);
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.

medium

你好,这里的断言可以更精确。我们明确知道 metadata-only-app 这个测试应用只注册了一个路由,所以可以直接判断 app.router.stack.length 是否等于 1,而不是 > 0。这样可以让测试用例更加健壮。

Suggested change
assert(app.router.stack.length > 0);
assert.strictEqual(app.router.stack.length, 1);

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/egg/test/start.test.ts`:
- Around line 15-17: The teardown in the afterAll blocks calls await app.close()
unguarded and will throw if beforeAll failed to set app; update both afterAll
handlers to check that the test App instance exists before calling close (e.g.,
if (app) await app.close() or use optional chaining) so teardown is skipped when
setup failed; locate the afterAll closures in this test file (referencing the
app variable used in beforeAll/afterAll) and add the existence guard in both
places.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 12f5d8b3-65c8-4486-afb2-45216789329a

📥 Commits

Reviewing files that changed from the base of the PR and between aa1c3b2 and 07e9277.

📒 Files selected for processing (6)
  • packages/egg/src/lib/loader/AppWorkerLoader.ts
  • packages/egg/test/fixtures/apps/metadata-only-app/app.js
  • packages/egg/test/fixtures/apps/metadata-only-app/app/controller/home.js
  • packages/egg/test/fixtures/apps/metadata-only-app/app/router.js
  • packages/egg/test/fixtures/apps/metadata-only-app/package.json
  • packages/egg/test/start.test.ts

Comment on lines +15 to +17
afterAll(async () => {
await app.close();
});
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.

⚠️ Potential issue | 🟡 Minor

Guard teardown against setup failure in afterAll.

If beforeAll fails, app can be unset and app.close() throws, which can mask the original failure (Line 16 and Line 40).

🛠️ Suggested fix
-    let app: SingleModeApplication;
+    let app: SingleModeApplication | undefined;
@@
     afterAll(async () => {
-      await app.close();
+      if (app) await app.close();
     });
@@
-    let app: SingleModeApplication;
+    let app: SingleModeApplication | undefined;
@@
     afterAll(async () => {
-      await app.close();
+      if (app) await app.close();
     });

Also applies to: 39-41

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/egg/test/start.test.ts` around lines 15 - 17, The teardown in the
afterAll blocks calls await app.close() unguarded and will throw if beforeAll
failed to set app; update both afterAll handlers to check that the test App
instance exists before calling close (e.g., if (app) await app.close() or use
optional chaining) so teardown is skipped when setup failed; locate the afterAll
closures in this test file (referencing the app variable used in
beforeAll/afterAll) and add the existence guard in both places.

@codecov
Copy link
Copy Markdown

codecov bot commented Mar 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.45%. Comparing base (aa1c3b2) to head (07e9277).
⚠️ Report is 1 commits behind head on next.

Additional details and impacted files
@@            Coverage Diff             @@
##             next    #5847      +/-   ##
==========================================
+ Coverage   85.39%   85.45%   +0.05%     
==========================================
  Files         666      666              
  Lines       13171    13171              
  Branches     1522     1522              
==========================================
+ Hits        11248    11255       +7     
+ Misses       1791     1785       -6     
+ Partials      132      131       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR extends Egg’s metadataOnly startup path (used for manifest generation) by preventing unnecessary route registration during metadata-only boot, and adds tests/fixtures to validate the behavior against normal startup.

Changes:

  • Skip AppWorkerLoader.loadRouter() when metadataOnly is enabled.
  • Add a dedicated fixture app (metadata-only-app) with lifecycle hooks and routes for comparison.
  • Add 6 tests covering metadataOnly vs normal mode: lifecycle hooks, router stack, and agent creation.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
packages/egg/src/lib/loader/AppWorkerLoader.ts Guard loadRouter() behind !options.metadataOnly to avoid route registration during metadata-only boot.
packages/egg/test/start.test.ts New test coverage comparing metadataOnly vs normal mode (lifecycle, router stack, agent).
packages/egg/test/fixtures/apps/metadata-only-app/package.json New fixture app package metadata.
packages/egg/test/fixtures/apps/metadata-only-app/app/router.js Fixture routes used to verify router registration is skipped in metadataOnly mode.
packages/egg/test/fixtures/apps/metadata-only-app/app/controller/home.js Fixture controller for the route.
packages/egg/test/fixtures/apps/metadata-only-app/app.js Fixture boot hook implementation recording lifecycle calls into bootLog.

Comment on lines +27 to +29
it('should not create agent', () => {
assert.strictEqual(app.agent, undefined);
});
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

In this test app is typed as SingleModeApplication (from test/utils.ts), where agent is declared as a required property. But here metadataOnly mode explicitly expects app.agent to be undefined, so the type annotation is misleading and reduces type-safety for future edits. Consider using a local type with agent?: for metadataOnly tests, or update the shared SingleModeApplication typing to reflect the metadataOnly case (e.g. conditional/union type or separate SingleModeApplicationMetadataOnly).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@jerryliang64 jerryliang64 left a comment

Choose a reason for hiding this comment

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

LGTM

@killagu killagu merged commit 957c693 into next Mar 30, 2026
44 of 48 checks passed
@killagu killagu deleted the feat/tegg-metadata-only branch March 30, 2026 11:28
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.

3 participants